[nemiver] Support graphically adding a variable to the monitor
- From: Dodji Seketeli <dodji src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver] Support graphically adding a variable to the monitor
- Date: Sun, 13 Nov 2011 18:41:51 +0000 (UTC)
commit 5c4b2227fd2477f224120575b42776d63549cddb
Author: Dodji Seketeli <dodji seketeli org>
Date: Sun Nov 13 15:26:10 2011 +0100
Support graphically adding a variable to the monitor
[This is not a proper commit entry. Commits on this branch are
all going to be re-hashed anyway.]
The variable inspector dialog now has a button that lets you add
the current variable/expression to the monitor. It's very rough as no
check is performed to make sure you can't add the same expression to the
monitor twice, etc. Also, once the variable is added, we face an issue
that is explained in #663959, namely the life time management of expressions
backed by variable objects. I need to address that issue separately
before getting back to this business.
src/persp/dbgperspective/nmv-dbg-perspective.cc | 19 ++
.../dbgperspective/nmv-var-inspector-dialog.cc | 31 ++++-
.../dbgperspective/nmv-var-inspector-dialog.h | 4 +
src/persp/dbgperspective/nmv-variables-utils.cc | 2 +-
src/persp/dbgperspective/nmv-vars-monitor.cc | 177 ++++++++++++++++++--
src/persp/dbgperspective/ui/varinspectordialog.ui | 17 ++-
6 files changed, 229 insertions(+), 21 deletions(-)
---
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index 48f4126..eb39062 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -285,6 +285,7 @@ private:
void on_toggle_breakpoint_enabled_action ();
void on_toggle_countpoint_action ();
void on_inspect_variable_action ();
+ void on_expr_monitoring_requested (const IDebugger::VariableSafePtr);
void on_call_function_action ();
void on_find_text_response_signal (int);
void on_breakpoint_delete_action
@@ -1631,6 +1632,21 @@ DBGPerspective::on_inspect_variable_action ()
}
void
+DBGPerspective::on_expr_monitoring_requested
+(const IDebugger::VariableSafePtr a_var)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ NEMIVER_TRY;
+
+ THROW_IF_FAIL (m_priv && m_priv->vars_monitor);
+
+ m_priv->vars_monitor->add_variable (a_var);
+
+ NEMIVER_CATCH;
+}
+
+void
DBGPerspective::on_call_function_action ()
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -7825,6 +7841,9 @@ DBGPerspective::inspect_variable (const UString &a_variable_name)
debugger (),
*this);
dialog.set_history (m_priv->var_inspector_dialog_history);
+ dialog.expr_monitoring_requested ().connect
+ (sigc::mem_fun (*this,
+ &DBGPerspective::on_expr_monitoring_requested));
if (a_variable_name != "") {
dialog.inspect_variable (a_variable_name);
}
diff --git a/src/persp/dbgperspective/nmv-var-inspector-dialog.cc b/src/persp/dbgperspective/nmv-var-inspector-dialog.cc
index 95ba726..e546bbd 100644
--- a/src/persp/dbgperspective/nmv-var-inspector-dialog.cc
+++ b/src/persp/dbgperspective/nmv-var-inspector-dialog.cc
@@ -51,11 +51,13 @@ class VarInspectorDialog::Priv {
Gtk::ComboBox *var_name_entry;
Glib::RefPtr<Gtk::ListStore> m_variable_history;
Gtk::Button *inspect_button;
+ Gtk::Button *add_to_monitor_button;
SafePtr<VarInspector> var_inspector;
Gtk::Dialog &dialog;
Glib::RefPtr<Gtk::Builder> gtkbuilder;
IDebuggerSafePtr debugger;
IPerspective &perspective;
+ sigc::signal<void, IDebugger::VariableSafePtr> expr_monitoring_requested;
Priv ();
public:
@@ -94,6 +96,11 @@ public:
"inspectbutton");
inspect_button->set_sensitive (false);
+ add_to_monitor_button =
+ ui_utils::get_widget_from_gtkbuilder<Gtk::Button> (gtkbuilder,
+ "addtomonitorbutton");
+ add_to_monitor_button->set_sensitive (false);
+
Gtk::Box *box =
ui_utils::get_widget_from_gtkbuilder<Gtk::Box> (gtkbuilder,
"inspectorwidgetbox");
@@ -116,6 +123,8 @@ public:
THROW_IF_FAIL (var_name_entry);
inspect_button->signal_clicked ().connect (sigc::mem_fun
(*this, &Priv::do_inspect_variable));
+ add_to_monitor_button->signal_clicked ().connect
+ (sigc::mem_fun (*this, &Priv::on_do_monitor_button_clicked));
var_name_entry->signal_changed ().connect (sigc::mem_fun
(*this, &Priv::on_var_name_changed_signal));
var_name_entry->get_entry()->signal_activate ().connect (sigc::mem_fun
@@ -266,8 +275,10 @@ public:
UString var_name = var_name_entry->get_entry ()->get_text ();
if (var_name == "") {
inspect_button->set_sensitive (false);
+ add_to_monitor_button->set_sensitive (false);
} else {
inspect_button->set_sensitive (true);
+ add_to_monitor_button->set_sensitive (true);
}
// this handler is called when any text is changed in the entry or when
@@ -281,6 +292,18 @@ public:
NEMIVER_CATCH
}
+ void
+ on_do_monitor_button_clicked ()
+ {
+ NEMIVER_TRY;
+
+ THROW_IF_FAIL (var_inspector->get_variable ());
+
+ expr_monitoring_requested.emit (var_inspector->get_variable ());
+
+ NEMIVER_CATCH
+ }
+
//************************
//</signal handlers>
//*************************
@@ -352,5 +375,11 @@ VarInspectorDialog::get_history (std::list<UString> &a_hist) const
m_priv->get_history (a_hist);
}
-NEMIVER_END_NAMESPACE (nemiver)
+sigc::signal<void, IDebugger::VariableSafePtr>&
+VarInspectorDialog::expr_monitoring_requested ()
+{
+ THROW_IF_FAIL (m_priv);
+ return m_priv->expr_monitoring_requested;
+}
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/dbgperspective/nmv-var-inspector-dialog.h b/src/persp/dbgperspective/nmv-var-inspector-dialog.h
index d02928f..383bca9 100644
--- a/src/persp/dbgperspective/nmv-var-inspector-dialog.h
+++ b/src/persp/dbgperspective/nmv-var-inspector-dialog.h
@@ -53,6 +53,10 @@ public:
const IDebugger::VariableSafePtr variable () const;
void set_history (const std::list<UString> &);
void get_history (std::list<UString> &) const;
+
+ // Signals
+
+ sigc::signal<void, IDebugger::VariableSafePtr>& expr_monitoring_requested ();
};//end class VarInspectorDialog
NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/dbgperspective/nmv-variables-utils.cc b/src/persp/dbgperspective/nmv-variables-utils.cc
index 2eed442..f4871a5 100644
--- a/src/persp/dbgperspective/nmv-variables-utils.cc
+++ b/src/persp/dbgperspective/nmv-variables-utils.cc
@@ -630,7 +630,7 @@ set_a_variable (const IDebugger::VariableSafePtr a_var,
bool
unlink_a_variable_row (const IDebugger::VariableSafePtr &a_var,
const Glib::RefPtr<Gtk::TreeStore> &a_store,
- Gtk::TreeModel::iterator &a_parent_row_it)
+ const Gtk::TreeModel::iterator &a_parent_row_it)
{
Gtk::TreeModel::iterator var_to_unlink_it;
if (!find_a_variable (a_var, a_parent_row_it, var_to_unlink_it))
diff --git a/src/persp/dbgperspective/nmv-vars-monitor.cc b/src/persp/dbgperspective/nmv-vars-monitor.cc
index afd8213..7ee6f7a 100644
--- a/src/persp/dbgperspective/nmv-vars-monitor.cc
+++ b/src/persp/dbgperspective/nmv-vars-monitor.cc
@@ -44,15 +44,24 @@ struct VarsMonitor::Priv
SafePtr<Gtk::TreeRowReference> in_scope_vars_row_ref;
SafePtr<Gtk::TreeRowReference> out_of_scope_vars_row_ref;
Gtk::TreeModel::iterator cur_selected_row;
- bool initialized;
IDebugger::VariableList monitored_variables;
map<IDebugger::VariableSafePtr, bool> in_scope_vars;
+ IDebugger::Frame saved_frame;
+ IDebugger::StopReason saved_reason;
+ bool saved_has_frame;
+ bool initialized;
+ bool is_new_frame;
+ bool is_up2date;
Priv (IDebugger &a_debugger,
IPerspective &a_perspective)
: debugger (a_debugger),
perspective (a_perspective),
- initialized (false)
+ saved_reason (IDebugger::UNDEFINED_REASON),
+ saved_has_frame (false),
+ initialized (false),
+ is_new_frame (true),
+ is_up2date (true)
{
// The widget is built lazily when somone requests it from
// the outside.
@@ -137,6 +146,13 @@ struct VarsMonitor::Priv
void
init_graphical_signals ()
{
+ THROW_IF_FAIL (tree_view);
+
+ tree_view->signal_row_expanded ().connect
+ (sigc::mem_fun (*this, &Priv::on_tree_view_row_expanded_signal));
+
+ tree_view->signal_draw ().connect_notify
+ (sigc::mem_fun (this, &Priv::on_draw_signal));
}
void
@@ -147,16 +163,60 @@ struct VarsMonitor::Priv
void
add_variable (const IDebugger::VariableSafePtr a_var)
{
- if (a_var)
- monitored_variables.push_back (a_var);
+ if (!a_var)
+ return;
+ monitored_variables.push_back (a_var);
+ Gtk::TreeModel::iterator root_node;
+ if (a_var->in_scope ())
+ get_in_scope_vars_row_iterator (root_node);
+ else
+ get_out_of_scope_vars_row_iterator (root_node);
+ THROW_IF_FAIL (root_node);
+ vutils::append_a_variable (a_var, *tree_view,
+ tree_store, root_node,
+ /*a_truncate_type=*/true);
}
void
add_variables (const IDebugger::VariableList &a_vars)
{
- IDebugger::VariableList::const_iterator it;
- for (it = a_vars.begin (); it != a_vars.end (); ++it)
- monitored_variables.push_back (*it);
+ IDebugger::VariableList::const_iterator it = a_vars.begin ();
+ for (; it != a_vars.end (); ++it)
+ add_variable (*it);
+ }
+
+ void
+ remove_variable (const IDebugger::VariableSafePtr a_var)
+ {
+ IDebugger::VariableList::iterator it = monitored_variables.begin ();
+ for (; it != monitored_variables.end (); ++it) {
+ if ((*it)->internal_name () == a_var->internal_name ()
+ || (*it)->equals_by_value (*a_var)) {
+ // Remove the graphical representation of the node,
+ // and then remove the node itself from the list of
+ // monitored variables.
+ Gtk::TreeModel::iterator parent_row;
+ if (a_var->in_scope ())
+ get_in_scope_vars_row_iterator (parent_row);
+ else
+ get_out_of_scope_vars_row_iterator (parent_row);
+ THROW_IF_FAIL (parent_row);
+ vutils::unlink_a_variable_row (a_var, tree_store, parent_row);
+ monitored_variables.erase (it);
+ // We removed an element from the array while
+ // iterating on it so the iterator is invalidated. We
+ // must not use it again.
+ break;
+ }
+ }
+ }
+
+ void
+ remove_variables (const IDebugger::VariableList &a_vars)
+ {
+ IDebugger::VariableList::const_iterator it = a_vars.begin ();
+ for (; it != a_vars.end (); ++it)
+ remove_variable (*it);
}
bool
@@ -233,9 +293,9 @@ struct VarsMonitor::Priv
}
void
- finish_handling_debugger_stopped_event (IDebugger::StopReason /*a_reason*/,
+ finish_handling_debugger_stopped_event (IDebugger::StopReason a_reason,
bool a_has_frame,
- const IDebugger::Frame &/*a_frame*/)
+ const IDebugger::Frame &a_frame)
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -243,11 +303,20 @@ struct VarsMonitor::Priv
THROW_IF_FAIL (tree_store);
- if (!a_has_frame)
+ LOG_DD ("stopped, reason: " << a_reason);
+ if (a_reason == IDebugger::EXITED_SIGNALLED
+ || a_reason == IDebugger::EXITED_NORMALLY
+ || a_reason == IDebugger::EXITED
+ || !a_has_frame) {
return;
+ }
- //TODO: walk the monitored variables and list those that have
- //changed.
+ is_new_frame = (saved_frame != a_frame);
+ saved_frame = a_frame;
+
+
+ // Walk the monitored variables and list those that have
+ // changed.
IDebugger::VariableList::const_iterator it;
for (it = monitored_variables.begin ();
it != monitored_variables.end ();
@@ -282,15 +351,20 @@ struct VarsMonitor::Priv
|| !a_has_frame)
return;
- if (should_process_now ())
+ if (should_process_now ()) {
finish_handling_debugger_stopped_event (a_reason,
a_has_frame,
a_frame);
+ } else {
+ saved_reason = a_reason;
+ saved_has_frame = a_has_frame;
+ is_up2date = false;
+ }
NEMIVER_CATCH;
}
void
- on_vars_changed (const IDebugger::VariableList &/*a_sub_vars*/,
+ on_vars_changed (const IDebugger::VariableList &a_sub_vars,
const IDebugger::VariableSafePtr a_var_root)
{
NEMIVER_TRY;
@@ -301,8 +375,73 @@ struct VarsMonitor::Priv
update_var_in_scope_or_not (a_var_root, var_it);
THROW_IF_FAIL (var_it);
- // TODO: Walk a_sub_vars (children of a_var_root) and update
- // them graphically, using update_a_variable.
+ // Walk children of a_var_root and update their graphical
+ // representation.
+ IDebugger::VariableList::const_iterator v = a_sub_vars.begin ();
+ for (; v != a_sub_vars.end (); ++v) {
+ vutils::update_a_variable (*v, *tree_view,
+ var_it,
+ /*a_truncate_type=*/false,
+ /*a_handle_highlight=*/true,
+ /*a_is_new_frame=*/is_new_frame,
+ /*a_update_members=*/false);
+ }
+ NEMIVER_CATCH;
+ }
+
+ void
+ on_tree_view_row_expanded_signal (const Gtk::TreeModel::iterator &a_it,
+ const Gtk::TreeModel::Path &a_path)
+ {
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ NEMIVER_TRY;
+
+ if (!(*a_it)[vutils::get_variable_columns ().needs_unfolding]) {
+ return;
+ }
+ LOG_DD ("A variable needs unfolding");
+
+ IDebugger::VariableSafePtr var =
+ (*a_it)[vutils::get_variable_columns ().variable];
+ debugger.unfold_variable
+ (var,
+ sigc::bind (sigc::mem_fun (*this,
+ &Priv::on_variable_unfolded_signal),
+ a_path));
+
+ NEMIVER_CATCH;
+ }
+
+ void
+ on_variable_unfolded_signal (const IDebugger::VariableSafePtr a_var,
+ const Gtk::TreeModel::Path a_var_node)
+ {
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ NEMIVER_TRY;
+
+ Gtk::TreeModel::iterator var_it = tree_store->get_iter (a_var_node);
+ vutils::update_unfolded_variable (a_var,
+ *tree_view,
+ tree_store,
+ var_it,
+ false /* do not truncate type */);
+ tree_view->expand_row (a_var_node, false);
+ NEMIVER_CATCH;
+ }
+
+ void
+ on_draw_signal (const Cairo::RefPtr<Cairo::Context> &)
+ {
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+ NEMIVER_TRY;
+ if (!is_up2date) {
+ finish_handling_debugger_stopped_event (saved_reason,
+ saved_has_frame,
+ saved_frame);
+ is_up2date = true;
+ }
NEMIVER_CATCH;
}
@@ -342,13 +481,15 @@ VarsMonitor::add_variables (const IDebugger::VariableList &a_vars)
}
void
-VarsMonitor::remove_variable (const IDebugger::VariableSafePtr /*a_var*/)
+VarsMonitor::remove_variable (const IDebugger::VariableSafePtr a_var)
{
+ m_priv->remove_variable (a_var);
}
void
-VarsMonitor::remove_variables (const std::list<IDebugger::VariableSafePtr> &/*a_vars*/)
+VarsMonitor::remove_variables (const std::list<IDebugger::VariableSafePtr> &a_vars)
{
+ m_priv->remove_variables (a_vars);
}
void
diff --git a/src/persp/dbgperspective/ui/varinspectordialog.ui b/src/persp/dbgperspective/ui/varinspectordialog.ui
index 5b6bf75..4fab8c4 100644
--- a/src/persp/dbgperspective/ui/varinspectordialog.ui
+++ b/src/persp/dbgperspective/ui/varinspectordialog.ui
@@ -19,6 +19,20 @@
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
+ <object class="GtkButton" id="addtomonitorbutton">
+ <property name="label" translatable="yes">Add to monitor</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkButton" id="okbutton">
<property name="label">gtk-close</property>
<property name="visible">True</property>
@@ -31,7 +45,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
@@ -133,6 +147,7 @@
</object>
</child>
<action-widgets>
+ <action-widget response="-3">addtomonitorbutton</action-widget>
<action-widget response="-7">okbutton</action-widget>
</action-widgets>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]