diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 970a315f4e..678dea3ecc 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -275,7 +275,6 @@ Application Debugger : BreakpointListView.cpp BreakpointsView.cpp ConsoleOutputView.cpp - ExpressionEvaluationWindow.cpp ExpressionPromptWindow.cpp ImageFunctionsView.cpp ImageListView.cpp diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp deleted file mode 100644 index 51a8b7b988..0000000000 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2014, Rene Gollent, rene@gollent.com. - * Distributed under the terms of the MIT License. - */ -#include "ExpressionEvaluationWindow.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "AutoLocker.h" - -#include "IntegerValue.h" -#include "MessageCodes.h" -#include "SourceLanguage.h" -#include "StackFrame.h" -#include "SyntheticPrimitiveType.h" -#include "Thread.h" -#include "UiUtils.h" -#include "UserInterface.h" - - -ExpressionEvaluationWindow::ExpressionEvaluationWindow( - SourceLanguage* language, StackFrame* frame, ::Thread* thread, - UserInterfaceListener* listener, BHandler* target) - : - BWindow(BRect(), "Evaluate Expression", B_FLOATING_WINDOW, - B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), - fLanguage(language), - fExpressionInfo(NULL), - fExpressionInput(NULL), - fExpressionOutput(NULL), - fEvaluateButton(NULL), - fListener(listener), - fStackFrame(frame), - fThread(thread), - fCloseTarget(target) -{ - fLanguage->AcquireReference(); - - if (fStackFrame != NULL) - fStackFrame->AcquireReference(); - - if (fThread != NULL) - fThread->AcquireReference(); -} - - -ExpressionEvaluationWindow::~ExpressionEvaluationWindow() -{ - fLanguage->ReleaseReference(); - - if (fStackFrame != NULL) - fStackFrame->ReleaseReference(); - - if (fThread != NULL) - fThread->ReleaseReference(); - - fExpressionInfo->ReleaseReference(); -} - - -ExpressionEvaluationWindow* -ExpressionEvaluationWindow::Create(SourceLanguage* language, StackFrame* frame, - ::Thread* thread, UserInterfaceListener* listener, BHandler* target) -{ - ExpressionEvaluationWindow* self = new ExpressionEvaluationWindow(language, - frame, thread, listener, target); - - try { - self->_Init(); - } catch (...) { - delete self; - throw; - } - - return self; - -} - - -void -ExpressionEvaluationWindow::_Init() -{ - fExpressionInfo = new ExpressionInfo; - fExpressionInfo->AddListener(this); - - fExpressionInput = new BTextControl("Expression:", NULL, - new BMessage(MSG_EVALUATE_EXPRESSION)); - BLayoutItem* labelItem = fExpressionInput->CreateLabelLayoutItem(); - BLayoutItem* inputItem = fExpressionInput->CreateTextViewLayoutItem(); - inputItem->SetExplicitMinSize(BSize(200.0, B_SIZE_UNSET)); - inputItem->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); - labelItem->View()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - - fExpressionOutput = new BStringView("ExpressionOutputView", NULL); - fExpressionOutput->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, - B_SIZE_UNSET)); - - BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) - .AddGroup(B_HORIZONTAL, 4.0f) - .Add(labelItem) - .Add(inputItem) - .End() - .AddGroup(B_HORIZONTAL, 4.0f) - .Add(new BStringView("OutputLabelView", "Result:")) - .Add(fExpressionOutput) - .End() - .AddGroup(B_HORIZONTAL, 4.0f) - .AddGlue() - .Add((fEvaluateButton = new BButton("Evaluate", - new BMessage(MSG_EVALUATE_EXPRESSION)))) - .End(); - - fExpressionInput->SetTarget(this); - fEvaluateButton->SetTarget(this); - fEvaluateButton->MakeDefault(true); - fExpressionInput->TextView()->MakeFocus(true); -} - - -void -ExpressionEvaluationWindow::ExpressionEvaluated(ExpressionInfo* info, - status_t result, ExpressionResult* value) -{ - BMessage message(MSG_EXPRESSION_EVALUATED); - message.AddInt32("result", result); - BReference reference; - if (value != NULL) { - message.AddPointer("value", value); - reference.SetTo(value); - } - - if (PostMessage(&message) == B_OK) - reference.Detach(); -} - - -void -ExpressionEvaluationWindow::Show() -{ - CenterOnScreen(); - BWindow::Show(); -} - - -bool -ExpressionEvaluationWindow::QuitRequested() -{ - BMessenger messenger(fCloseTarget); - messenger.SendMessage(MSG_EXPRESSION_WINDOW_CLOSED); - - return BWindow::QuitRequested(); -} - - -void -ExpressionEvaluationWindow::MessageReceived(BMessage* message) -{ - switch (message->what) { - case MSG_EVALUATE_EXPRESSION: - { - if (fExpressionInput->TextView()->TextLength() == 0) - break; - - fExpressionInfo->SetTo(fExpressionInput->Text()); - - fListener->ExpressionEvaluationRequested(fLanguage, - fExpressionInfo, fStackFrame, fThread); - break; - } - case MSG_EXPRESSION_EVALUATED: - { - ExpressionResult* value = NULL; - BReference reference; - if (message->FindPointer("value", - reinterpret_cast(&value)) == B_OK) { - reference.SetTo(value, true); - } - - BString outputText; - if (value != NULL) { - if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) { - Value* primitive = value->PrimitiveValue(); - if (dynamic_cast(primitive) != NULL) { - BVariant variantValue; - primitive->ToVariant(variantValue); - primitive->ToString(outputText); - outputText.SetToFormat("%#" B_PRIx64 " (%s)", - variantValue.ToUInt64(), outputText.String()); - } else - primitive->ToString(outputText); - } else { - outputText.SetToFormat("Unsupported result type: %d", - value->Kind()); - } - } else { - status_t result; - if (message->FindInt32("result", &result) != B_OK) - result = B_ERROR; - - outputText.SetToFormat("Failed to evaluate expression: %s", - strerror(result)); - } - - fExpressionOutput->SetText(outputText); - break; - } - default: - BWindow::MessageReceived(message); - break; - } - -} diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h deleted file mode 100644 index e985667b96..0000000000 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2014, Rene Gollent, rene@gollent.com. - * Distributed under the terms of the MIT License. - */ -#ifndef EXPRESSION_EVALUATION_WINDOW_H -#define EXPRESSION_EVALUATION_WINDOW_H - - -#include - -#include "ExpressionInfo.h" - - -class BButton; -class BStringView; -class BTextControl; -class Thread; -class SourceLanguage; -class StackFrame; -class UserInterfaceListener; - - -class ExpressionEvaluationWindow : public BWindow, - private ExpressionInfo::Listener -{ -public: - ExpressionEvaluationWindow( - SourceLanguage* language, - StackFrame* frame, - ::Thread* thread, - UserInterfaceListener* listener, - BHandler* target); - - ~ExpressionEvaluationWindow(); - - static ExpressionEvaluationWindow* Create( - SourceLanguage* language, - StackFrame* frame, - ::Thread* thread, - UserInterfaceListener* listener, - BHandler* target); - // throws - - - virtual void MessageReceived(BMessage* message); - - virtual void Show(); - virtual bool QuitRequested(); - -private: - void _Init(); - - // ExpressionInfo::Listener - virtual void ExpressionEvaluated(ExpressionInfo* info, - status_t result, ExpressionResult* value); - -private: - SourceLanguage* fLanguage; - ExpressionInfo* fExpressionInfo; - BTextControl* fExpressionInput; - BStringView* fExpressionOutput; - BButton* fEvaluateButton; - UserInterfaceListener* fListener; - StackFrame* fStackFrame; - ::Thread* fThread; - BHandler* fCloseTarget; -}; - -#endif // EXPRESSION_EVALUATION_WINDOW_H diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp index 7e59844ee4..6c142b5873 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp @@ -13,15 +13,16 @@ ExpressionPromptWindow::ExpressionPromptWindow(BHandler* addTarget, - BHandler* closeTarget) + BHandler* closeTarget, bool isPersistent) : - BWindow(BRect(), "Add Expression", B_FLOATING_WINDOW, - B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), + BWindow(BRect(), isPersistent ? "Add Expression" : "Evaluate Expression", + B_FLOATING_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), fExpressionInput(NULL), fCancelButton(NULL), fAddButton(NULL), fAddTarget(addTarget), - fCloseTarget(closeTarget) + fCloseTarget(closeTarget), + fPersistentExpression(isPersistent) { } @@ -32,10 +33,11 @@ ExpressionPromptWindow::~ExpressionPromptWindow() ExpressionPromptWindow* -ExpressionPromptWindow::Create(BHandler* addTarget, BHandler* closeTarget) +ExpressionPromptWindow::Create(BHandler* addTarget, BHandler* closeTarget, + bool isPersistent) { ExpressionPromptWindow* self = new ExpressionPromptWindow(addTarget, - closeTarget); + closeTarget, isPersistent); try { self->_Init(); @@ -108,6 +110,7 @@ ExpressionPromptWindow::MessageReceived(BMessage* message) { BMessage addMessage(MSG_EXPRESSION_PROMPT_WINDOW_CLOSED); addMessage.AddString("expression", fExpressionInput->Text()); + addMessage.AddBool("persistent", fPersistentExpression); addMessage.AddMessenger("target", BMessenger(fAddTarget)); BMessenger(fCloseTarget).SendMessage(&addMessage); diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h index ce18792f55..ca5b43a636 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h @@ -17,12 +17,13 @@ class ExpressionPromptWindow : public BWindow { public: ExpressionPromptWindow(BHandler* addTarget, - BHandler* closeTarget); + BHandler* closeTarget, bool isPersistent); ~ExpressionPromptWindow(); static ExpressionPromptWindow* Create(BHandler* addTarget, - BHandler* closeTarget); + BHandler* closeTarget, + bool isPersistent); // throws @@ -40,6 +41,7 @@ private: BButton* fAddButton; BHandler* fAddTarget; BHandler* fCloseTarget; + bool fPersistentExpression; }; #endif // EXPRESSION_PROMPT_WINDOW_H diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index 0f8f101fda..7dbb0f9ca6 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -41,7 +41,6 @@ #include "CpuState.h" #include "DisassembledCode.h" #include "BreakpointEditWindow.h" -#include "ExpressionEvaluationWindow.h" #include "ExpressionPromptWindow.h" #include "FileSourceCode.h" #include "GuiSettingsUtils.h" @@ -142,7 +141,6 @@ TeamWindow::TeamWindow(::Team* team, UserInterfaceListener* listener) fBreakConditionConfigWindow(NULL), fBreakpointEditWindow(NULL), fInspectorWindow(NULL), - fExpressionWindow(NULL), fExpressionPromptWindow(NULL), fFilePanel(NULL), fActiveSourceWorker(-1) @@ -170,9 +168,9 @@ TeamWindow::~TeamWindow() if (fInspectorWindow->Lock()) fInspectorWindow->Quit(); } - if (fExpressionWindow != NULL) { - if (fExpressionWindow->Lock()) - fExpressionWindow->Quit(); + if (fExpressionPromptWindow != NULL) { + if (fExpressionPromptWindow->Lock()) + fExpressionPromptWindow->Quit(); } fTeam->RemoveListener(this); @@ -348,39 +346,12 @@ TeamWindow::MessageReceived(BMessage* message) } case MSG_SHOW_EXPRESSION_WINDOW: - { - if (fExpressionWindow != NULL) { - AutoLocker lock(fExpressionWindow); - if (lock.IsLocked()) - fExpressionWindow->Activate(true); - } else { - try { - SourceLanguage* language = NULL; - if (_GetActiveSourceLanguage(language) != B_OK) - break; - - BReference languageReference(language, - true); - fExpressionWindow = ExpressionEvaluationWindow::Create( - language, fActiveStackFrame, fActiveThread, fListener, - this); - if (fExpressionWindow != NULL) - fExpressionWindow->Show(); - } catch (...) { - // TODO: notify user - } - } - break; - } - case MSG_EXPRESSION_WINDOW_CLOSED: - { - fExpressionWindow = NULL; - break; - } case MSG_SHOW_EXPRESSION_PROMPT_WINDOW: { BHandler* addTarget; - if (message->FindPointer("target", + if (message->what == MSG_SHOW_EXPRESSION_WINDOW) + addTarget = fVariablesView; + else if (message->FindPointer("target", reinterpret_cast(&addTarget)) != B_OK) { break; } @@ -391,8 +362,13 @@ TeamWindow::MessageReceived(BMessage* message) fExpressionPromptWindow->Activate(true); } else { try { + // if the request was initiated via the evaluate + // expression top level menu item, then this evaluation + // should not be persisted. + bool persistentExpression = + message->what == MSG_SHOW_EXPRESSION_PROMPT_WINDOW; fExpressionPromptWindow = ExpressionPromptWindow::Create( - addTarget, this); + addTarget, this, persistentExpression); if (fExpressionPromptWindow != NULL) fExpressionPromptWindow->Show(); } catch (...) { @@ -401,6 +377,7 @@ TeamWindow::MessageReceived(BMessage* message) } break; } + case MSG_EXPRESSION_WINDOW_CLOSED: case MSG_EXPRESSION_PROMPT_WINDOW_CLOSED: { fExpressionPromptWindow = NULL; @@ -410,8 +387,11 @@ TeamWindow::MessageReceived(BMessage* message) if (message->FindString("expression", &expression) == B_OK && message->FindMessenger("target", &targetMessenger) == B_OK) { + BMessage addMessage(MSG_ADD_NEW_EXPRESSION); addMessage.AddString("expression", expression); + addMessage.AddBool("persistent", message->FindBool( + "persistent")); targetMessenger.SendMessage(&addMessage); } diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h index d42dec4916..d9f5dfa7e9 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h @@ -34,7 +34,6 @@ class BTabView; class ConsoleOutputView; class BreakConditionConfigWindow; class BreakpointEditWindow; -class ExpressionEvaluationWindow; class ExpressionPromptWindow; class Image; class InspectorWindow; @@ -231,7 +230,6 @@ private: BreakConditionConfigWindow* fBreakConditionConfigWindow; BreakpointEditWindow* fBreakpointEditWindow; InspectorWindow* fInspectorWindow; - ExpressionEvaluationWindow* fExpressionWindow; ExpressionPromptWindow* fExpressionPromptWindow; GuiTeamUiSettings fUiSettings; BFilePanel* fFilePanel; diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 45c6ddd897..0b58a6954c 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -1740,6 +1740,7 @@ VariablesView::VariablesView(Listener* listener) fExpressionChildren(10, false), fTableCellContextMenuTracker(NULL), fPendingTypecastInfo(NULL), + fTemporaryExpression(NULL), fFrameClearPending(false), fListener(listener) { @@ -1764,6 +1765,9 @@ VariablesView::~VariablesView() delete fContainerListener; if (fPendingTypecastInfo != NULL) fPendingTypecastInfo->ReleaseReference(); + + if (fTemporaryExpression != NULL) + fTemporaryExpression->ReleaseReference(); } @@ -2060,8 +2064,11 @@ VariablesView::MessageReceived(BMessage* message) if (message->FindString("expression", &expression) != B_OK) break; + bool persistentExpression = message->FindBool("persistent"); + ExpressionInfo* info; - status_t error = _AddExpression(expression, info); + status_t error = _AddExpression(expression, persistentExpression, + info); if (error != B_OK) { // TODO: notify user of failure break; @@ -2096,8 +2103,13 @@ VariablesView::MessageReceived(BMessage* message) fPendingTypecastInfo->ReleaseReference(); fPendingTypecastInfo = NULL; } - } else + } else { _AddExpressionNode(info, result, value); + if (info == fTemporaryExpression) { + info->ReleaseReference(); + fTemporaryExpression = NULL; + } + } break; } @@ -2828,29 +2840,33 @@ VariablesView::_CopyVariableValueToClipboard() status_t -VariablesView::_AddExpression(const char* expression, ExpressionInfo*& _info) +VariablesView::_AddExpression(const char* expression, + bool persistentExpression, ExpressionInfo*& _info) { - // if our stack frame doesn't have an associated function, - // we can't add an expression - FunctionInstance* function = fStackFrame->Function(); - if (function == NULL) - return B_NOT_ALLOWED; + ExpressionInfoEntry* entry = NULL; + if (persistentExpression) { + // if our stack frame doesn't have an associated function, + // we can't add an expression + FunctionInstance* function = fStackFrame->Function(); + if (function == NULL) + return B_NOT_ALLOWED; - FunctionID* id = function->GetFunctionID(); - if (id == NULL) - return B_NO_MEMORY; - - BReference idReference(id, true); - - ExpressionInfoEntry* entry = fExpressions->Lookup(FunctionKey(id)); - if (entry == NULL) { - entry = new(std::nothrow) ExpressionInfoEntry(id); - if (entry == NULL) + FunctionID* id = function->GetFunctionID(); + if (id == NULL) return B_NO_MEMORY; - status_t error = fExpressions->Insert(entry); - if (error != B_OK) { - delete entry; - return error; + + BReference idReference(id, true); + + entry = fExpressions->Lookup(FunctionKey(id)); + if (entry == NULL) { + entry = new(std::nothrow) ExpressionInfoEntry(id); + if (entry == NULL) + return B_NO_MEMORY; + status_t error = fExpressions->Insert(entry); + if (error != B_OK) { + delete entry; + return error; + } } } @@ -2861,8 +2877,11 @@ VariablesView::_AddExpression(const char* expression, ExpressionInfo*& _info) BReference infoReference(info, true); - if (!entry->AddItem(info)) - return B_NO_MEMORY; + if (persistentExpression) { + if (!entry->AddItem(info)) + return B_NO_MEMORY; + } else + fTemporaryExpression = info; info->AddListener(this); infoReference.Detach(); @@ -2926,6 +2945,7 @@ void VariablesView::_AddExpressionNode(ExpressionInfo* info, status_t result, ExpressionResult* value) { + bool temporaryExpression = (info == fTemporaryExpression); Variable* variable = NULL; BReference variableReference; BVariant valueData; @@ -2990,9 +3010,12 @@ VariablesView::_AddExpressionNode(ExpressionInfo* info, status_t result, child->Node()->SetLocationAndValue(NULL, explicitValue, B_OK); } - if (fExpressionChildren.AddItem(child)) { + if (temporaryExpression || fExpressionChildren.AddItem(child)) { child->AcquireReference(); + if (temporaryExpression) + return; + // attempt to restore our newly added node's view state, // if applicable. FunctionID* functionID = fStackFrame->Function() diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h index 81568b8ce5..b19ed15b6c 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h @@ -114,6 +114,7 @@ private: void _CopyVariableValueToClipboard(); status_t _AddExpression(const char* expression, + bool persistentExpression, ExpressionInfo*& _info); void _RemoveExpression(ModelNode* node); @@ -140,6 +141,7 @@ private: ExpressionChildList fExpressionChildren; TableCellContextMenuTracker* fTableCellContextMenuTracker; VariablesExpressionInfo* fPendingTypecastInfo; + ExpressionInfo* fTemporaryExpression; bool fFrameClearPending; Listener* fListener; };