From 9b0d97576d41083cf9df72be49ea3c2e83683d7a Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Wed, 22 Jul 2015 22:38:18 -0400 Subject: [PATCH] Debugger: Add variable editing utility window. VariableEditWindow: - Implement container window for variable value editors. While not as ideal as initially intended, this will handle presenting value editing to the user until more work is done on the table cell editing aspect of things. --- src/apps/debugger/Jamfile | 1 + src/apps/debugger/MessageCodes.h | 3 + .../utility_windows/VariableEditWindow.cpp | 185 ++++++++++++++++++ .../gui/utility_windows/VariableEditWindow.h | 59 ++++++ 4 files changed, 248 insertions(+) create mode 100644 src/apps/debugger/user_interface/gui/utility_windows/VariableEditWindow.cpp create mode 100644 src/apps/debugger/user_interface/gui/utility_windows/VariableEditWindow.h 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