[PATCH 2/5] Allow opt-in points when inspecting a variable



It turned out to be very useful to be able to define actions to be
performed whenever the user asks to inspects an expression in the
variable inspector.  This patch basically defines a new
VarInspectorDialog::inspect_variable method that takes a signal
slot (a generalization of a callback function pointer) that is to be
invoked whenever the expression is materialized and evaluated in the
expression inspector dialog.  It also defines new signals that are
emitted by the VarInspector whenever an expression is evaluated and
when it is cleared.

Tested and applying to master.

	* src/persp/dbgperspective/nmv-var-inspector-dialog.h
	(VarInspectorDialog::inspect_variable): Declare new overload.
	* src/persp/dbgperspective/nmv-var-inspector.h
	(VarInspector::inspect_variable): New overload.
	(VarInspector::{var_inspected_signal, cleared_signal}): New methods.
	* src/persp/dbgperspective/nmv-var-inspector-dialog.cc
	(VarInspectorDialog::Priv::do_inspect_variable): Cleanup.
	(VarInspectorDialog::Priv::inspect_variable)
	(VarInspectorDialog::inspect_variable): New overload that takes a
	slot called upon inspection of the expression.  Re-write the
	former overload in terms of the new one.
	(VarInspectorDialog::Priv::on_variable_inspected): New default
	callback invoked upon expression inspection.
	(VarInspectorDialog::Priv::on_variable_inspector_cleared): New default
	callback invoked upon expression inspection.
	(VarInspectorDialog::Priv::build_dialog): Add comment.  Connect
	the new on_variable_inspector_cleared callback to the
	cleared_signal of the inspector.
	* src/persp/dbgperspective/nmv-var-inspector.cc
	(no_op_void_variable_slot): New no-op slot.
	(VarInspector::Priv::{var_inspected_signal,cleared_signal}) New
	members.
	(VarInspector::Priv::create_variable): New overload that takes a
	slot called upon creation of the expression.  Re-write the former
	overload in terms of the new one.
	(VarInspector::Priv::on_variable_created_signal): Take a slot to
	call upon the creation of the variable.
	(VarInspector::inspect_variable): New overload that takes a slot
	called upon creation of the expression.  Re-write the former
	overload in terms of the new one.
	(VarInspector::var_inspected_signal)
	(VarInspector::cleared_signal): New signal getters.
---
 .../dbgperspective/nmv-var-inspector-dialog.cc     |   92 +++++++++++++++-
 .../dbgperspective/nmv-var-inspector-dialog.h      |    3 +
 src/persp/dbgperspective/nmv-var-inspector.cc      |  109 ++++++++++++++++++-
 src/persp/dbgperspective/nmv-var-inspector.h       |   10 ++
 4 files changed, 202 insertions(+), 12 deletions(-)

diff --git a/src/persp/dbgperspective/nmv-var-inspector-dialog.cc b/src/persp/dbgperspective/nmv-var-inspector-dialog.cc
index 5aeda14..6b5856d 100644
--- a/src/persp/dbgperspective/nmv-var-inspector-dialog.cc
+++ b/src/persp/dbgperspective/nmv-var-inspector-dialog.cc
@@ -76,6 +76,9 @@ public:
         connect_to_widget_signals ();
     }
 
+    /// Build the inspector dialog.
+    ///
+    /// Fetch widgets from gtkbuilder and initialize them.
     void
     build_dialog ()
     {
@@ -97,9 +100,13 @@ public:
         Gtk::Box *box =
             ui_utils::get_widget_from_gtkbuilder<Gtk::Box> (gtkbuilder,
                                                        "inspectorwidgetbox");
+
         var_inspector.reset (new VarInspector (debugger, perspective));
         var_inspector->enable_contextual_menu (true);
-        THROW_IF_FAIL (var_inspector);
+        var_inspector->cleared_signal ().connect
+            (sigc::mem_fun
+             (*this,
+              &VarInspectorDialog::Priv::on_variable_inspector_cleared));
 
         Gtk::ScrolledWindow *scr = Gtk::manage (new Gtk::ScrolledWindow);
         scr->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
@@ -122,27 +129,61 @@ public:
                 (*this, &Priv::do_inspect_variable));
     }
 
+    /// Inspect the variable (or, more generally the expression) which
+    /// name the user has typed in the variable name entry, in the UI.
     void 
     do_inspect_variable ()
     {
-        NEMIVER_TRY
+        NEMIVER_TRY;
 
         THROW_IF_FAIL (var_name_entry);
 
         UString var_name = var_name_entry->get_entry ()->get_text ();
-        if (var_name == "") {return;}
-        inspect_variable (var_name, true);
+        if (var_name == "")
+            return;
 
-        NEMIVER_CATCH
+        inspect_variable (var_name, /*expand=*/true);
+
+        NEMIVER_CATCH;
     }
 
+    /// Inspect an expression.
+    ///
+    /// \param a_expr the expression to inspect.
+    ///
+    /// \param a_expand whether to expand the resulting expression
+    /// tree.
     void
     inspect_variable (const UString& a_expr,
                       bool a_expand)
     {
+        inspect_variable (a_expr, a_expand, 
+                          sigc::mem_fun
+                          (*this,
+                           &VarInspectorDialog::Priv::on_variable_inspected));
+    }
+
+    /// Inspect an expression.
+    ///
+    /// \param a_expr the expression to inspect.
+    ///
+    /// \param a_expand whether to expand the resulting expression
+    /// tree.
+    ///
+    /// \param a_s a slot to invoke whenever the expresion has been
+    /// inspected.
+    void
+    inspect_variable (const UString &a_expr,
+                      bool a_expand,
+                      const sigc::slot<void, 
+                                       const IDebugger::VariableSafePtr> &a_s)
+    {
         THROW_IF_FAIL (var_inspector);
         THROW_IF_FAIL (m_variable_history);
-        var_inspector->inspect_variable (a_expr, a_expand);
+
+        var_inspector->inspect_variable
+            (a_expr, a_expand, a_s);
+
         add_to_history (a_expr,
                         false /*append*/,
                         false /*don't allow duplicates*/);
@@ -254,6 +295,8 @@ public:
     //<signal handlers>
     //*************************
 
+    /// Handler called when the name of the variable changes in the
+    /// variable name entry field.
     void
     on_var_name_changed_signal ()
     {
@@ -281,6 +324,19 @@ public:
         NEMIVER_CATCH
     }
 
+    /// Handler called when the variable to be inspected is actually
+    /// added to the inspector.
+    void
+    on_variable_inspected (const IDebugger::VariableSafePtr)
+    {
+    }
+
+    /// Handler called when the variable inspector is cleared.
+    void
+    on_variable_inspector_cleared ()
+    {
+    }
+
     //************************
     //</signal handlers>
     //*************************
@@ -314,6 +370,9 @@ VarInspectorDialog::variable_name () const
     return m_priv->var_name_entry->get_entry ()->get_text ();
 }
 
+/// Inspect an expression (including a variable)
+///
+/// \param a_var_name the expression to inspect.
 void
 VarInspectorDialog::inspect_variable (const UString &a_var_name)
 {
@@ -326,6 +385,27 @@ VarInspectorDialog::inspect_variable (const UString &a_var_name)
     }
 }
 
+/// Inspect an expression (including a variable)
+///
+/// \param a_var_name the expression to inspect.
+///
+/// \param a_slot a slot to invoke whenever the expression has been
+/// inspected.
+void
+VarInspectorDialog::inspect_variable
+(const UString &a_var_name,
+ const sigc::slot<void, 
+                  const IDebugger::VariableSafePtr> &a_slot)
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->var_name_entry);
+
+    if (a_var_name != "") {
+        m_priv->var_name_entry->get_entry ()->set_text (a_var_name);
+        m_priv->inspect_variable (a_var_name, true, a_slot);
+    }
+}
+
 const IDebugger::VariableSafePtr
 VarInspectorDialog::variable () const
 {
diff --git a/src/persp/dbgperspective/nmv-var-inspector-dialog.h b/src/persp/dbgperspective/nmv-var-inspector-dialog.h
index d02928f..6f59adc 100644
--- a/src/persp/dbgperspective/nmv-var-inspector-dialog.h
+++ b/src/persp/dbgperspective/nmv-var-inspector-dialog.h
@@ -50,6 +50,9 @@ public:
 
     UString variable_name () const;
     void inspect_variable (const UString &a_variable_name);
+    void inspect_variable (const UString &a_variable_name,
+			   const sigc::slot<void, 
+			                    const IDebugger::VariableSafePtr> &);
     const IDebugger::VariableSafePtr variable () const;
     void set_history (const std::list<UString> &);
     void get_history (std::list<UString> &) const;
diff --git a/src/persp/dbgperspective/nmv-var-inspector.cc b/src/persp/dbgperspective/nmv-var-inspector.cc
index dd3f3c5..256ea98 100644
--- a/src/persp/dbgperspective/nmv-var-inspector.cc
+++ b/src/persp/dbgperspective/nmv-var-inspector.cc
@@ -45,6 +45,12 @@ using cmn::DynamicModuleManager;
 
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 
+/// A no-op variable slot.
+static void
+no_op_void_variable_slot (const IDebugger::VariableSafePtr)
+{
+}
+
 class VarInspector::Priv : public sigc::trackable {
     friend class VarInspector;
     Priv ();
@@ -68,6 +74,9 @@ class VarInspector::Priv : public sigc::trackable {
     IVarWalkerSafePtr varobj_walker;
     DynamicModuleManager *module_manager;
     Glib::RefPtr<Gtk::UIManager> ui_manager;
+    mutable sigc::signal<void,
+                         const IDebugger::VariableSafePtr> var_inspected_signal;
+    mutable sigc::signal<void> cleared_signal;
 
     void
     build_widget ()
@@ -233,16 +242,46 @@ class VarInspector::Priv : public sigc::trackable {
         ui_utils::display_info (message);
     }
 
+    /// Creates a variable (or more generally, an expression).
+    ///
+    /// \param a_name the expression (or name of the variable) to
+    /// create.
+    ///
+    /// \param a_expand whethet to expand the tree representing the
+    /// expression that is going to be created, or not.
     void
     create_variable (const UString &a_name,
                      bool a_expand)
     {
+        create_variable (a_name, a_expand, &no_op_void_variable_slot);
+    }
+
+    /// Creates a variable (or more generally, an expression).
+    ///
+    /// \param a_name the expression (or name of the variable) to
+    /// create.
+    ///
+    /// \param a_expand whethet to expand the tree representing the
+    /// expression that is going to be created, or not.
+    ///
+    /// \param a_slot a slot (an abstraction of a handler function)
+    /// that is invoked whenever the resulting expression is added to
+    /// the inspector.
+    void
+    create_variable (const UString &a_name,
+                     bool a_expand,
+                     const sigc::slot<void, 
+                                      const IDebugger::VariableSafePtr> &a_slot)
+    {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
 
         expand_variable = a_expand;
         debugger->create_variable
-            (a_name, sigc::mem_fun
-                    (this, &VarInspector::Priv::on_variable_created_signal));
+            (a_name,
+             sigc::bind
+             (sigc::mem_fun
+              (this, &VarInspector::Priv::on_variable_created_signal),
+              a_slot));
     }
 
     Glib::RefPtr<Gtk::UIManager> get_ui_manager ()
@@ -487,14 +526,27 @@ class VarInspector::Priv : public sigc::trackable {
         NEMIVER_CATCH
     }
 
+    /// A handler called whenever a variable is created in the
+    /// debugger interface, as a result of the user requesting that we
+    /// inspect it.  The function then adds the variable into the
+    /// inspector.
+    ///
+    /// \param a_var the created variable
+    ///
+    /// \param a_slot a handler to be called whenever the variable is
+    /// added to the inspector.
     void
-    on_variable_created_signal (const IDebugger::VariableSafePtr a_var)
+    on_variable_created_signal (const IDebugger::VariableSafePtr a_var,
+                                sigc::slot<void, 
+                                           const IDebugger::VariableSafePtr> &a_slot)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
 
         NEMIVER_TRY;
 
         set_variable (a_var, expand_variable, re_visualize);
+        var_inspected_signal.emit (a_var);
+        a_slot (a_var);
 
         NEMIVER_CATCH;
     }
@@ -643,16 +695,45 @@ VarInspector::set_variable (IDebugger::VariableSafePtr a_variable,
     m_priv->set_variable (a_variable, a_expand, a_revisualize);
 }
 
+/// Inspect a variable/expression.
+///
+/// \param a_variable_name the name of the variable, or more
+/// generally, the expression to the inspected.
+///
+/// \param a_expand whether to expand the resulting tree representing
+/// the expression.
+void
+VarInspector::inspect_variable (const UString &a_variable_name,
+                                bool a_expand)
+{
+    inspect_variable (a_variable_name,
+                      a_expand,
+                      &no_op_void_variable_slot);
+}
+
+/// Inspect a variable/expression.
+///
+/// \param a_variable_name the name of the variable, or more
+/// generally, the expression to the inspected.
+///
+/// \param a_expand whether to expand the resulting tree representing
+/// the expression.
+///
+/// \param a_s a slot (handler function) to be invoked whenever the
+/// resulting tree (representing the expression to the inspected) is
+/// added to the inspector.
 void
 VarInspector::inspect_variable (const UString &a_variable_name,
-                                 bool a_expand)
+                                bool a_expand,
+                                const sigc::slot<void, 
+                                                 const IDebugger::VariableSafePtr> &a_s)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
     if (a_variable_name == "") {return;}
     THROW_IF_FAIL (m_priv);
     m_priv->re_init_tree_view ();
-    m_priv->create_variable (a_variable_name, a_expand);
+    m_priv->create_variable (a_variable_name, a_expand, a_s);
 }
 
 IDebugger::VariableSafePtr
@@ -684,5 +765,21 @@ VarInspector::clear ()
     m_priv->re_init_tree_view ();
 }
 
-NEMIVER_END_NAMESPACE (nemiver)
+/// A signal emitted when the variable to be inspected is added to the
+/// inspector.
+sigc::signal<void, const IDebugger::VariableSafePtr>&
+VarInspector::var_inspected_signal () const
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->var_inspected_signal;
+}
 
+/// A signal emitted when the inspector is cleared.
+sigc::signal<void>&
+VarInspector::cleared_signal () const
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->cleared_signal;
+}
+
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/dbgperspective/nmv-var-inspector.h b/src/persp/dbgperspective/nmv-var-inspector.h
index 406eacc..1414c71 100644
--- a/src/persp/dbgperspective/nmv-var-inspector.h
+++ b/src/persp/dbgperspective/nmv-var-inspector.h
@@ -57,10 +57,20 @@ public:
 		       bool a_re_visualize = false);
     void inspect_variable (const UString &a_variable_name,
                            bool a_expand = false);
+    void inspect_variable (const UString &a_variable_name,
+                           bool a_expand,
+			   const sigc::slot<void, 
+			              const IDebugger::VariableSafePtr> &a_s);
     IDebugger::VariableSafePtr get_variable () const;
     void enable_contextual_menu (bool a_flag);
     bool is_contextual_menu_enabled () const;
     void clear ();
+
+    // Signals
+    sigc::signal<void, const IDebugger::VariableSafePtr>&
+      var_inspected_signal () const;
+    sigc::signal<void>& cleared_signal () const;
+
 };//end class VarInspector
 
 NEMIVER_END_NAMESPACE (nemiver)
-- 
		Dodji


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]