From d88d941c90bb26795b81a9bb676abeb1e628df8d Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Thu, 23 Jul 2015 22:49:58 -0400 Subject: [PATCH] Debugger: Finish variable edit support. VariablesView: - Intercept table node invocations. If the invocation corresponds to a writable variable, request a corresponding editor and bring up a an edit window for it. - Handle requests from the edit window to write the final updated value of the variable. This implements the last missing piece for ticket #9708, except for an editor for floats. --- .../gui/team_window/VariablesView.cpp | 114 ++++++++++++++++++ .../gui/team_window/VariablesView.h | 8 +- 2 files changed, 120 insertions(+), 2 deletions(-) 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 a9ac19fec1..9e37618d26 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -43,6 +43,7 @@ #include "StringUtils.h" #include "StringValue.h" #include "SyntheticPrimitiveType.h" +#include "TableCellValueEditor.h" #include "TableCellValueRenderer.h" #include "Team.h" #include "TeamDebugInfo.h" @@ -59,6 +60,7 @@ #include "ValueNode.h" #include "ValueNodeManager.h" #include "Variable.h" +#include "VariableEditWindow.h" #include "VariableValueNodeChild.h" #include "VariablesViewState.h" #include "VariablesViewStateHistory.h" @@ -1773,6 +1775,7 @@ VariablesView::VariablesView(Listener* listener) fPendingTypecastInfo(NULL), fTemporaryExpression(NULL), fFrameClearPending(false), + fEditWindow(NULL), fListener(listener) { SetName("Variables"); @@ -1781,6 +1784,9 @@ VariablesView::VariablesView(Listener* listener) VariablesView::~VariablesView() { + if (fEditWindow != NULL) + BMessenger(fEditWindow).SendMessage(B_QUIT_REQUESTED); + SetStackFrame(NULL, NULL); fVariableTable->SetTreeTableModel(NULL); @@ -1887,6 +1893,66 @@ VariablesView::MessageReceived(BMessage* message) Looper()->PostMessage(message); break; } + case MSG_SHOW_VARIABLE_EDIT_WINDOW: + { + TableCellValueEditor* editor = NULL; + if (message->FindPointer("editor", reinterpret_cast( + &editor)) != B_OK) { + break; + } + BReference editorReference(editor, true); + if (fEditWindow != NULL) + fEditWindow->Activate(); + else { + ValueNode* node = NULL; + if (message->FindPointer("node", reinterpret_cast( + &node)) != B_OK) { + break; + } + + Value* value = NULL; + if (message->FindPointer("value", reinterpret_cast( + &value)) != B_OK) { + break; + } + + try { + fEditWindow = VariableEditWindow::Create(value, node, + editor, this); + } catch (...) { + fEditWindow = NULL; + break; + } + + fEditWindow->Show(); + } + break; + } + case MSG_VARIABLE_EDIT_WINDOW_CLOSED: + { + fEditWindow = NULL; + break; + } + case MSG_WRITE_VARIABLE_VALUE: + { + Value* value = NULL; + if (message->FindPointer("value", reinterpret_cast( + &value)) != B_OK) { + break; + } + + BReference valueReference(value, true); + + ValueNode* node = NULL; + if (message->FindPointer("node", reinterpret_cast( + &node)) != B_OK) { + break; + } + + fListener->ValueNodeWriteRequested(node, + fStackFrame->GetCpuState(), value); + break; + } case MSG_SHOW_TYPECAST_NODE_PROMPT: { BMessage* promptMessage = new(std::nothrow) BMessage( @@ -2328,6 +2394,54 @@ VariablesView::TreeTableNodeExpandedChanged(TreeTable* table, } +void +VariablesView::TreeTableNodeInvoked(TreeTable* table, + const TreeTablePath& path) +{ + ModelNode* node = (ModelNode*)fVariableTableModel->NodeForPath(path); + if (node == NULL) + return; + + ValueNodeChild* child = node->NodeChild(); + + if (child->LocationResolutionState() != B_OK) + return; + + ValueLocation* location = child->Location(); + if (!location->IsWritable()) + return; + + Value* value = node->GetValue(); + if (value == NULL) + return; + + // get a value handler + ValueHandler* valueHandler; + status_t error = ValueHandlerRoster::Default()->FindValueHandler(value, + valueHandler); + if (error != B_OK) + return; + + BReference handlerReference(valueHandler, true); + TableCellValueRenderer* renderer = node->TableCellRenderer(); + TableCellValueEditor* editor = NULL; + error = valueHandler->GetTableCellValueEditor(value, + renderer != NULL ? renderer->GetSettings() : NULL, editor); + if (error != B_OK || editor == NULL) + return; + + BReference editorReference(editor, true); + + BMessage message(MSG_SHOW_VARIABLE_EDIT_WINDOW); + message.AddPointer("editor", editor); + message.AddPointer("node", node->NodeChild()->Node()); + message.AddPointer("value", value); + + if (BMessenger(this).SendMessage(&message) == B_OK) + editorReference.Detach(); +} + + void VariablesView::TreeTableCellMouseDown(TreeTable* table, const TreeTablePath& path, int32 columnIndex, BPoint screenWhere, 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 50d264edd4..f515e59fc2 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2012-2014, Rene Gollent, rene@gollent.com. + * Copyright 2012-2015, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef VARIABLES_VIEW_H @@ -22,11 +22,13 @@ class StackFrame; class Thread; class Type; class TypeComponentPath; +class ValueLocation; class ValueNode; class ValueNodeChild; class ValueNodeContainer; class Value; class Variable; +class VariableEditWindow; class VariablesViewState; class VariablesViewStateHistory; @@ -59,7 +61,8 @@ private: // TreeTableListener virtual void TreeTableNodeExpandedChanged(TreeTable* table, const TreeTablePath& path, bool expanded); - + virtual void TreeTableNodeInvoked(TreeTable* table, + const TreeTablePath& path); virtual void TreeTableCellMouseDown(TreeTable* table, const TreeTablePath& path, int32 columnIndex, BPoint screenWhere, @@ -143,6 +146,7 @@ private: VariablesExpressionInfo* fPendingTypecastInfo; ExpressionInfo* fTemporaryExpression; bool fFrameClearPending; + VariableEditWindow* fEditWindow; Listener* fListener; };