diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 648b3cf693..a8c60b316b 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -304,6 +304,7 @@ local sources = ExpressionPromptWindow.cpp SignalDispositionEditWindow.cpp StartTeamWindow.cpp + VariableEditWindow.cpp WatchPromptWindow.cpp # user_interface/gui/value diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h index 450bade7ab..89604a8f6a 100644 --- a/src/apps/debugger/MessageCodes.h +++ b/src/apps/debugger/MessageCodes.h @@ -82,6 +82,8 @@ enum { MSG_SHOW_EXPRESSION_PROMPT_WINDOW = 'sepw', MSG_ADD_NEW_EXPRESSION = 'anex', MSG_EXPRESSION_PROMPT_WINDOW_CLOSED = 'epwc', + MSG_SHOW_VARIABLE_EDIT_WINDOW = 'svew', + MSG_VARIABLE_EDIT_WINDOW_CLOSED = 'vewc', MSG_INSPECT_ADDRESS = 'isad', MSG_WRITE_TARGET_MEMORY = 'wtam', MSG_EVALUATE_EXPRESSION = 'evex', @@ -93,6 +95,7 @@ enum { MSG_SHOW_CONTAINER_RANGE_PROMPT = 'scrp', MSG_SET_CONTAINER_RANGE = 'chcr', MSG_GENERATE_DEBUG_REPORT = 'gdrp', + MSG_WRITE_VARIABLE_VALUE = 'wrvv', MSG_DEBUG_INFO_NEEDS_USER_INPUT = 'dnui', MSG_USER_INTERFACE_FILE_CHOSEN = 'uifc' diff --git a/src/apps/debugger/user_interface/gui/utility_windows/VariableEditWindow.cpp b/src/apps/debugger/user_interface/gui/utility_windows/VariableEditWindow.cpp new file mode 100644 index 0000000000..da4f96258d --- /dev/null +++ b/src/apps/debugger/user_interface/gui/utility_windows/VariableEditWindow.cpp @@ -0,0 +1,185 @@ +/* + * Copyright 2015, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "VariableEditWindow.h" + +#include +#include +#include +#include + +#include "MessageCodes.h" +#include "TableCellValueEditor.h" +#include "Value.h" +#include "ValueNode.h" + + +enum { + MSG_VARIABLE_VALUE_CHANGED = 'vavc' +}; + + +VariableEditWindow::VariableEditWindow(Value* initialValue, ValueNode* node, + TableCellValueEditor* editor, BHandler* target) + : + BWindow(BRect(), "Edit value", + B_FLOATING_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), + fCancelButton(NULL), + fSaveButton(NULL), + fTarget(target), + fNode(node), + fInitialValue(initialValue), + fNewValue(NULL), + fEditor(editor) +{ + fNode->AcquireReference(); + fInitialValue->AcquireReference(); + fEditor->AcquireReference(); + fEditor->AddListener(this); +} + + +VariableEditWindow::~VariableEditWindow() +{ + fNode->ReleaseReference(); + fInitialValue->ReleaseReference(); + if (fNewValue != NULL) + fNewValue->ReleaseReference(); + + fEditor->RemoveListener(this); + fEditor->ReleaseReference(); +} + + +VariableEditWindow* +VariableEditWindow::Create(Value* initialValue, ValueNode* node, + TableCellValueEditor* editor, BHandler* target) +{ + VariableEditWindow* self = new VariableEditWindow(initialValue, node, + editor, target); + + try { + self->_Init(); + } catch (...) { + delete self; + throw; + } + + return self; + +} + + +void +VariableEditWindow::_Init() +{ + BString label; + BString initialValue; + fInitialValue->ToString(initialValue); + label.SetToFormat("Initial value for '%s': %s\n", + fNode->Name().String(), initialValue.String()); + + BLayoutBuilder::Group<>(this, B_VERTICAL) + .SetInsets(B_USE_DEFAULT_SPACING) + .AddGroup(B_HORIZONTAL, 4.0f) + .Add(new BStringView("initialLabel", label)) + .End() + .AddGroup(B_HORIZONTAL, 4.0f) + .Add(new BStringView("newLabel", "New value:")) + .Add(fEditor->GetView()) + .End() + .AddGroup(B_HORIZONTAL, 4.0f) + .AddGlue() + .Add((fCancelButton = new BButton("Cancel", + new BMessage(B_QUIT_REQUESTED)))) + .Add((fSaveButton = new BButton("Save", + new BMessage(MSG_WRITE_VARIABLE_VALUE)))) + .End(); + + fCancelButton->SetTarget(this); + fSaveButton->SetTarget(this); + fSaveButton->MakeDefault(true); + fEditor->GetView()->MakeFocus(true); +} + + +void +VariableEditWindow::Show() +{ + CenterOnScreen(); + BWindow::Show(); +} + + +bool +VariableEditWindow::QuitRequested() +{ + fEditor->GetView()->RemoveSelf(); + + BMessenger messenger(fTarget); + messenger.SendMessage(MSG_VARIABLE_EDIT_WINDOW_CLOSED); + + return BWindow::QuitRequested(); +} + + +void +VariableEditWindow::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_VARIABLE_VALUE_CHANGED: + { + Value* value; + if (message->FindPointer("value", + reinterpret_cast(&value)) == B_OK) { + if (fNewValue != NULL) + fNewValue->ReleaseReference(); + + fNewValue = value; + } + break; + } + case MSG_WRITE_VARIABLE_VALUE: + { + BMessage message(MSG_WRITE_VARIABLE_VALUE); + message.AddPointer("node", fNode); + message.AddPointer("value", fNewValue); + + // acquire a reference on behalf of the target + BReference valueReference(fNewValue); + if (BMessenger(fTarget).SendMessage(&message) == B_OK) { + valueReference.Detach(); + PostMessage(B_QUIT_REQUESTED); + } + break; + } + default: + BWindow::MessageReceived(message); + break; + } +} + + +void +VariableEditWindow::TableCellEditBeginning() +{ +} + + +void +VariableEditWindow::TableCellEditCancelled() +{ + PostMessage(B_QUIT_REQUESTED); +} + + +void +VariableEditWindow::TableCellEditEnded(Value* newValue) +{ + BReference valueReference(newValue); + BMessage message(MSG_VARIABLE_VALUE_CHANGED); + message.AddPointer("value", newValue); + if (PostMessage(&message) == B_OK) + valueReference.Detach(); +} diff --git a/src/apps/debugger/user_interface/gui/utility_windows/VariableEditWindow.h b/src/apps/debugger/user_interface/gui/utility_windows/VariableEditWindow.h new file mode 100644 index 0000000000..987c552f4d --- /dev/null +++ b/src/apps/debugger/user_interface/gui/utility_windows/VariableEditWindow.h @@ -0,0 +1,59 @@ +/* + * Copyright 2015, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef VARIABLE_EDIT_WINDOW_H +#define VARIABLE_EDIT_WINDOW_H + + +#include + +#include "TableCellValueEditor.h" + + +class BButton; +class Value; +class ValueNode; + + +class VariableEditWindow : public BWindow, + private TableCellValueEditor::Listener { +public: + VariableEditWindow(Value* initialValue, + ValueNode* node, + TableCellValueEditor* editor, + BHandler* target); + + ~VariableEditWindow(); + + static VariableEditWindow* Create(Value* initialValue, + ValueNode* node, + TableCellValueEditor* editor, + BHandler* closeTarget); + // throws + + + virtual void MessageReceived(BMessage* message); + + virtual void Show(); + virtual bool QuitRequested(); + + // TableCellValueEditor::Listener + virtual void TableCellEditBeginning(); + virtual void TableCellEditCancelled(); + virtual void TableCellEditEnded(Value* newValue); + +private: + void _Init(); + +private: + BButton* fCancelButton; + BButton* fSaveButton; + BHandler* fTarget; + ValueNode* fNode; + Value* fInitialValue; + Value* fNewValue; + TableCellValueEditor* fEditor; +}; + +#endif // VARIABLE_EDIT_WINDOW_H