[nemiver/el6-branch] 560235 Initial support of "jump to"



commit 3935d90700c0426d04157a0b336cd6ce8d85afde
Author: Dodji Seketeli <dodji seketeli org>
Date:   Thu Apr 21 22:22:36 2011 +0200

    560235 Initial support of "jump to"
    
        	* src/dbgengine/nmv-i-debugger.h (IDebugger::jump_to_position):
    	New entry point.
    	(IDebugger::set_breakpoint, IDebugger::enable_breakpoint): New
    	overloads taking callback slots.
    	* src/dbgengine/nmv-gdb-engine.h (GDBEngine::jump_to_position)
    	(GDBEngine::enable_breakpoint): Declare these functions.
    	* src/dbgengine/nmv-gdb-engine.cc
    	(OnBreakpointHandler::do_handle): Support callback slots for
    	'-break-enable' and 'jump-to-position'.
    	(GDBEngine::jump_to_position, location_to_string): Define new
    	functions.
    	(GDBEngine::enable_breakpoint): Likewise.  Rewrite the other
    	overload in terms of this one.
    	* src/uicommon/nmv-source-editor.cc
    	(SourceEditor::current_location): New overload that returns a
    	pointer to const Loc.
    	* src/uicommon/nmv-source-editor.h: Likewise.
    	* src/persp/nmv-set-jump-to-dialog.h: New file.
    	* rc/persp/nmv-set-jump-to-dialog.cc: Likewise.
    	* src/persp/dbgperspective/ui/setjumptodialog.ui: Likewise.
    	* src/persp/dbgperspective/ui/Makefile.am: Add setjumptodialog.ui
    	to build system.
    	* src/persp/dbgperspective/Makefile.am: Add
    	nmv-set-jump-to-dialog.h and nmv-set-jump-to-dialog.cc to the
    	build system.
    	* src/persp/dbgperspective/nmv-dbg-perspective.cc
    	(DBGPerspective::on_jump_to_current_location_action)
    	(DBGPerspective::on_jump_and_break_to_current_location_action)
    	(DBGPerspective::on_break_before_jump)
    	(DBGPerspective::do_jump_to_current_location)
    	(DBGPerspective::do_jump_and_break_to_current_location)
    	(DBGPerspective::jump_to_location)
    	(DBGPerspective::on_jump_to_location_action)
    	(DBGPerspective::do_jump_and_break_to_location)
    	(DBGPerspective::jump_to_location_from_dialog)
    	(DBGPerspective::is_breakpoint_set_at_location): New functions.
    	(DBGPerspective::on_debugger_breakpoints_set_signal): Minor style
    	cleanup.
    	(DBGPerspective::init_actions): Add
    	JumpToCurrentLocationMenuItemAction and
    	JumpAndBreakToCurrentLocationMenuItemAction actions.  Add a menu
    	item to display a dialog to jump to a given location.
    	(DBGPerspective::get_contextual_menu): Add two new menu items for
    	actions JumpToCurrentLocationMenuItemAction and
    	(DBGPerspective::is_breakpoint_set_at_address): Add a boolean
    	output parameter to get the enable-ness of the breakpoint.
    	(DBGPerspective::get_breakpoint): New overload that takes a
    	location in argument.
    	(DBGPerspective::is_breakpoint_set_at_line): Add comment.
    	(DBGPerspective::toggle_breakpoint): Adjust for the new signature
    	of is_breakpoint_set_at_address.
    	JumpAndBreakToCurrentLocationMenuItemAction.
    	* src/persp/dbgperspective/menus/menus.xml: Add add menu item to
    	jump to a specified location.
    	* po/POTFILES.in: Add
    	src/persp/dbgperspective/ui/setjumptodialog.ui to the list of
    	files containing translatable strings.

 po/POTFILES.in                                     |    1 +
 src/dbgengine/nmv-gdb-engine.cc                    |   92 ++++-
 src/dbgengine/nmv-gdb-engine.h                     |    7 +
 src/dbgengine/nmv-i-debugger.h                     |   13 +
 src/persp/dbgperspective/Makefile.am               |    4 +-
 src/persp/dbgperspective/menus/menus.xml           |    5 +-
 src/persp/dbgperspective/nmv-dbg-perspective.cc    |  430 ++++++++++++++++++-
 src/persp/dbgperspective/nmv-set-jump-to-dialog.cc |  465 ++++++++++++++++++++
 src/persp/dbgperspective/nmv-set-jump-to-dialog.h  |   58 +++
 src/persp/dbgperspective/ui/Makefile.am            |    3 +-
 src/persp/dbgperspective/ui/setjumptodialog.ui     |  281 ++++++++++++
 src/uicommon/nmv-source-editor.cc                  |   31 ++
 src/uicommon/nmv-source-editor.h                   |    3 +
 13 files changed, 1370 insertions(+), 23 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3b727c5..f48c425 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -16,6 +16,7 @@ src/uicommon/nmv-locate-file-dialog.cc
 [type: gettext/glade]src/persp/dbgperspective/ui/chooseoverloadsdialog.ui
 [type: gettext/glade]src/persp/dbgperspective/ui/remotetargetdialog.ui
 [type: gettext/glade]src/persp/dbgperspective/ui/setbreakpointdialog.ui
+[type: gettext/glade]src/persp/dbgperspective/ui/setjumptodialog.ui
 src/persp/dbgperspective/nmv-choose-overloads-dialog.cc
 [type: gettext/glade]src/persp/dbgperspective/ui/globalvarsinspector.ui
 [type: gettext/glade]src/persp/dbgperspective/ui/watchpointdialog.ui
diff --git a/src/dbgengine/nmv-gdb-engine.cc b/src/dbgengine/nmv-gdb-engine.cc
index a68645a..599b029 100644
--- a/src/dbgengine/nmv-gdb-engine.cc
+++ b/src/dbgengine/nmv-gdb-engine.cc
@@ -141,20 +141,20 @@ location_to_string (const Loc &a_loc,
         THROW ("Should not be reached");
 
     case Loc::SOURCE_LOC_KIND: {
-        const SourceLoc *loc = static_cast<const SourceLoc*> (&a_loc);
-        location_to_string (*loc, a_str);
+        const SourceLoc &loc = static_cast<const SourceLoc&> (a_loc);
+        location_to_string (loc, a_str);
     }
         break;
 
     case Loc::FUNCTION_LOC_KIND: {
-        const FunctionLoc *loc = static_cast<const FunctionLoc*> (&a_loc);
-        location_to_string (*loc, a_str);
+        const FunctionLoc &loc = static_cast<const FunctionLoc&> (a_loc);
+        location_to_string (loc, a_str);
     }
         break;
 
     case Loc::ADDRESS_LOC_KIND: {
-        const AddressLoc *loc = static_cast<const AddressLoc*> (&a_loc);
-        location_to_string (*loc, a_str);
+        const AddressLoc &loc = static_cast<const AddressLoc&> (a_loc);
+        location_to_string (loc, a_str);
     }
         break;
     }
@@ -1726,6 +1726,13 @@ struct OnCommandDoneHandler : OutputHandler {
             }
         }
 
+        if (a_in.command ().name () == "-break-enable"
+            && a_in.command ().has_slot ()) {
+            IDebugger::BreakpointsSlot slot =
+                a_in.command ().get_slot<IDebugger::BreakpointsSlot> ();
+            slot (m_engine->get_cached_breakpoints ());
+        }
+
         // So, if we are still attached to the target and we receive
         // a "DONE" response from GDB, it means we are READY.
         // But if we are not attached -- which can mean that the
@@ -1764,7 +1771,13 @@ struct OnRunningHandler : OutputHandler {
     void do_handle (CommandAndOutput &a_in)
     {
         LOG_FUNCTION_SCOPE_NORMAL_DD;
-        if (a_in.has_command ()) {}
+
+        Command &c = a_in.command ();
+        if (c.name () == "jump-to-position"
+            && c.has_slot ()) {
+            IDebugger::DefaultSlot s = c.get_slot<IDebugger::DefaultSlot> ();
+            s ();
+        }
         m_engine->running_signal ().emit ();
     }
 };//struct OnRunningHandler
@@ -3898,6 +3911,30 @@ GDBEngine::continue_to_position (const UString &a_path,
                             a_cookie));
 }
 
+/// Jump to a location in the inferior.
+///
+/// Execution is then resumed from the new location.
+///
+/// \param a_loc the location to jump to
+///
+/// \param a_slot a callback function that is invoked once the jump is
+/// done.
+void
+GDBEngine::jump_to_position (const Loc &a_loc,
+                             const DefaultSlot &a_slot)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    UString location;
+
+    location_to_string (a_loc, location);
+
+    Command command ("jump-to-position",
+                     "-exec-jump " + location);
+    command.set_slot (a_slot);
+    queue_command (command);
+}
+
 /// Set a breakpoint at a location in the inferior.
 ///
 /// \param a_loc the location of the breakpoint.
@@ -4012,18 +4049,51 @@ GDBEngine::set_breakpoint (const Address &a_address,
     queue_command (Command (cmd_name, break_cmd, a_cookie));
 }
 
+/// Enable a given breakpoint
+///
+/// \param a_break_num the ID of the breakpoint to enable.
+///
+/// \param a_slot a callback slot invoked upon completion of the
+/// command by GDB.
+///
+/// \param a_cookie a string passed as an argument to
+/// IDebugger::breakpoints_set_signal upon completion of the command
+/// by GDB.  Note that both a_slot and
+/// IDebugger::breakpoints_set_signal are invoked upon completion of
+/// the command by GDB for now.  Eventually only a_slot will be kept;
+/// IDebugger::breakpoints_set_signal will be dropped.  We in a
+/// transitional period at the moment.
 void
 GDBEngine::enable_breakpoint (gint a_break_num,
+                              const BreakpointsSlot &a_slot,
                               const UString &a_cookie)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
-    queue_command (Command ("enable-breakpoint",
-                            "-break-enable "
-                             + UString::from_int (a_break_num),
-                            a_cookie));
+    
+    Command command ("enable-breakpoint",
+                     "-break-enable "
+                     + UString::from_int (a_break_num));
+    command.set_slot (a_slot);
+    queue_command (command);
     list_breakpoints (a_cookie);
 }
 
+/// Enable a given breakpoint
+///
+/// \param a_break_num the ID of the breakpoint to enable.
+///
+/// \param a_cookie a string passed as an argument to
+/// IDebugger::breakpoints_set_signal upon completion of the command
+/// by GDB.  Eventually this function should be dropped and we should
+/// keep the one above.
+void
+GDBEngine::enable_breakpoint (gint a_break_num,
+                              const UString &a_cookie)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+    enable_breakpoint (a_break_num, &null_breakpoints_slot, a_cookie);
+}
+
 void
 GDBEngine::disable_breakpoint (gint a_break_num,
                                const UString &a_cookie)
diff --git a/src/dbgengine/nmv-gdb-engine.h b/src/dbgengine/nmv-gdb-engine.h
index f907081..980b61a 100644
--- a/src/dbgengine/nmv-gdb-engine.h
+++ b/src/dbgengine/nmv-gdb-engine.h
@@ -333,6 +333,9 @@ public:
                                gint a_line_num,
                                const UString &a_cookie) ;
 
+    void jump_to_position (const Loc &a_loc,
+			   const DefaultSlot &a_slot);
+
     void set_breakpoint (const Loc &a_loc,
 			 const UString &a_condition,
 			 gint a_ignore_count,
@@ -356,6 +359,10 @@ public:
                          const UString &a_cookie);
 
     void enable_breakpoint (gint a_break_num,
+			    const BreakpointsSlot &a_slot,
+			    const UString &a_cookie = "");
+
+    void enable_breakpoint (gint a_break_num,
                             const UString &a_cookie="");
 
     void disable_breakpoint (gint a_break_num,
diff --git a/src/dbgengine/nmv-i-debugger.h b/src/dbgengine/nmv-i-debugger.h
index a2dbac9..b375798 100644
--- a/src/dbgengine/nmv-i-debugger.h
+++ b/src/dbgengine/nmv-i-debugger.h
@@ -822,9 +822,15 @@ public:
     }
 
     typedef sigc::slot<void> DefaultSlot;
+
     typedef sigc::slot<void,
                        const std::pair<int, const IDebugger::Breakpoint&>&>
         BreakpointSlot;
+
+    typedef sigc::slot<void,
+                       const std::map<int, IDebugger::Breakpoint>&>
+        BreakpointsSlot;
+
     typedef sigc::slot<void, Loc&> LocSlot;
     
     virtual ~IDebugger () {}
@@ -1128,6 +1134,9 @@ public:
                                        gint a_line_num,
                                        const UString &a_cookie="") = 0;
 
+    virtual void jump_to_position (const Loc &a_loc,
+                                   const DefaultSlot &a_slot) = 0;
+
     virtual void set_breakpoint (const common::Loc &a_loc,
                                  const UString &a_condition,
                                  gint a_ignore_count,
@@ -1151,6 +1160,10 @@ public:
                                  const UString &a_cookie = "") = 0;
 
     virtual void enable_breakpoint (gint a_break_num,
+                                    const BreakpointsSlot &a_slot,
+                                    const UString &a_cookie="") = 0;
+
+    virtual void enable_breakpoint (gint a_break_num,
                                     const UString &a_cookie="") = 0;
 
     virtual void disable_breakpoint (gint a_break_num,
diff --git a/src/persp/dbgperspective/Makefile.am b/src/persp/dbgperspective/Makefile.am
index 12bf939..e615457 100644
--- a/src/persp/dbgperspective/Makefile.am
+++ b/src/persp/dbgperspective/Makefile.am
@@ -75,7 +75,9 @@ $(h)/nmv-dbg-perspective.h \
 $(h)/nmv-vars-treeview.h \
 $(h)/nmv-vars-treeview.cc \
 $(h)/nmv-call-function-dialog.h \
-$(h)/nmv-call-function-dialog.cc
+$(h)/nmv-call-function-dialog.cc \
+$(h)/nmv-set-jump-to-dialog.h \
+$(h)/nmv-set-jump-to-dialog.cc
 
 if BUILD_MEMORYVIEW
 memoryview_sources = \
diff --git a/src/persp/dbgperspective/menus/menus.xml b/src/persp/dbgperspective/menus/menus.xml
index 8653782..a771d65 100644
--- a/src/persp/dbgperspective/menus/menus.xml
+++ b/src/persp/dbgperspective/menus/menus.xml
@@ -63,9 +63,12 @@
             <menuitem action="NextMenuItemAction" name="NextMenuItem"/>
             <menuitem action="StepMenuItemAction" name="StepMenuItem"/>
             <menuitem action="StepOutMenuItemAction" name="StepOutMenuItem"/>
-            <menuitem action="StepInAsmMenuItemAction" name="StepInAsmMenuItem"/>
+            <menuitem action="StepInAsmMenuItemAction"
+		      name="StepInAsmMenuItem"/>
             <menuitem action="StepOverAsmMenuItemAction"
                       name="StepOverAsmMenuItem"/>
+	    <menuitem action="JumpToLocationMenuItemAction"
+                      name="JumpToLocationMenuItem"/>
             <separator/>
             <menuitem action="ToggleBreakpointMenuItemAction"
                 name="ToggleBreakMenuItem"/>
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index e43032b..54c95cf 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -64,6 +64,7 @@
 #include "common/nmv-date-utils.h"
 #include "common/nmv-str-utils.h"
 #include "common/nmv-address.h"
+#include "common/nmv-loc.h"
 #include "nmv-sess-mgr.h"
 #include "nmv-dbg-perspective.h"
 #include "nmv-source-editor.h"
@@ -99,9 +100,11 @@
 #endif // WITH_MEMORYVIEW
 #include "nmv-watchpoint-dialog.h"
 #include "nmv-debugger-utils.h"
+#include "nmv-set-jump-to-dialog.h"
 
 using namespace std;
 using namespace nemiver::common;
+using namespace nemiver::debugger_utils;
 using namespace nemiver::ui_utils;
 using namespace gtksourceview;
 
@@ -236,6 +239,12 @@ private:
     void on_step_over_asm_action ();
     void on_continue_action ();
     void on_continue_until_action ();
+    void on_jump_to_location_action ();
+    void on_jump_to_current_location_action ();
+    void on_jump_and_break_to_current_location_action ();
+    void on_break_before_jump (const std::pair<int,
+                                               const IDebugger::Breakpoint&>&,
+                               const Loc &a_loc);
     void on_set_breakpoint_action ();
     void on_set_breakpoint_using_dialog_action ();
     void on_set_watchpoint_using_dialog_action ();
@@ -600,6 +609,12 @@ public:
     void step_over_asm ();
     void do_continue ();
     void do_continue_until ();
+    void do_jump_to_current_location ();
+    void do_jump_and_break_to_location (const Loc&);
+    void do_jump_and_break_to_current_location ();
+    void jump_to_location (const map<int, IDebugger::Breakpoint>&,
+                           const Loc &);
+    void jump_to_location_from_dialog (const SetJumpToDialog &);
     void set_breakpoint_at_current_line_using_dialog ();
     void set_breakpoint ();
     void set_breakpoint (const UString &a_file,
@@ -616,9 +631,9 @@ public:
     void append_breakpoints
                     (const map<int, IDebugger::Breakpoint> &a_breaks);
 
+    const IDebugger::Breakpoint* get_breakpoint (const Loc&) const;
     const IDebugger::Breakpoint* get_breakpoint (const UString &a_file_name,
                                                  int a_linenum) const;
-
     const IDebugger::Breakpoint* get_breakpoint (const Address &) const;
 
     bool delete_breakpoint ();
@@ -626,10 +641,12 @@ public:
     bool delete_breakpoint (const UString &a_file_path,
                             int a_linenum);
     bool delete_breakpoint (const Address &a_address);
+    bool is_breakpoint_set_at_location (const Loc&, bool&);
     bool is_breakpoint_set_at_line (const UString &a_file_path,
                                     int a_linenum,
                                     bool &a_enabled);
-    bool is_breakpoint_set_at_address (const Address &);
+    bool is_breakpoint_set_at_address (const Address &,
+                                       bool&);
     void toggle_breakpoint (const UString &a_file_path,
                             int a_linenum);
     void toggle_breakpoint (const Address &a_address);
@@ -1010,7 +1027,6 @@ struct DBGPerspective::Priv {
     list<UString> call_expr_history;
     list<UString> var_inspector_dialog_history;
 
-
     Priv () :
         initialized (false),
         reused_session (false),
@@ -1546,6 +1562,102 @@ DBGPerspective::on_continue_until_action ()
     NEMIVER_CATCH
 }
 
+/// This function is called when the user activates the action
+/// "JumpToLocationMenuItemAction".  You can Look at
+/// DBGPerspective::init_actions to see how it is defined.  It
+/// basically lets the user choose the location where she wants to
+/// jump to, and instruct IDebugger to jump there.
+void
+DBGPerspective::on_jump_to_location_action ()
+{
+    SetJumpToDialog dialog (plugin_path ());
+
+    SourceEditor *editor = get_current_source_editor ();
+
+    // If the user has selected a current location (possibly to jump
+    // to), then pre-fill the dialog with that location.
+    SafePtr<const Loc> cur_loc;
+    if (editor)
+        cur_loc.reset (editor->current_location ());
+    if (cur_loc)
+        dialog.set_location (*cur_loc);
+
+    // By default, set a breakpoint to the location we are jumping to,
+    // so that execution stops after the jump.
+    dialog.set_break_at_location (true);
+
+    // Set the default file name to the file being currently visited,
+    // so that when the user enters a blank file name, the dialog
+    // knows what file name she is talking about.
+    if (editor
+        && editor->get_buffer_type () == SourceEditor::BUFFER_TYPE_SOURCE) {
+        dialog.set_current_file_name (get_current_file_path ());
+    }
+
+    // Now run the dialog and if the user hit anything but the OK
+    // button a the end, consider that she wants to cancel this
+    // procedure.
+    int result = dialog.run ();
+    if (result != Gtk::RESPONSE_OK)
+        return;
+
+    // By now we should have a proper location to jump to, so really
+    // perfom the jumping.
+    jump_to_location_from_dialog (dialog);
+}
+
+/// Callback function invoked when the menu item action "jump to
+/// current location" is activated.
+///
+/// It jumps to the location selected by the user in the source
+/// editor.
+void
+DBGPerspective::on_jump_to_current_location_action ()
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    NEMIVER_TRY
+    do_jump_to_current_location ();
+    NEMIVER_CATCH
+}
+
+/// Callback function invoked when the menu item action "setting a
+/// breakpoint to current lcoation and jump here" is activated.
+///
+/// It sets a breakpoint to the current location and jumps here.  So
+/// is transfered to the location selected by the user in the source
+/// editor and is stopped there.
+void
+DBGPerspective::on_jump_and_break_to_current_location_action ()
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    NEMIVER_TRY
+    do_jump_and_break_to_current_location ();
+    NEMIVER_CATCH
+}
+
+/// This callback is invoked right after a breakpoint is set as part
+/// of a "set a breakpoint and jump there" process.
+///
+/// So this function jumps to the position given in parameter.
+///
+/// \param a_loc the location to jump to.  This is also the location
+/// of the breakpoint that was set previously and which triggered this
+/// callback.
+void
+DBGPerspective::on_break_before_jump
+(const std::pair<int,
+                 const IDebugger::Breakpoint&> &,
+ const Loc &a_loc)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+    
+    NEMIVER_TRY;
+    debugger ()->jump_to_position (a_loc, &null_default_slot);
+    NEMIVER_CATCH;
+}
+
 void
 DBGPerspective::on_toggle_breakpoint_action ()
 {
@@ -2498,6 +2610,13 @@ DBGPerspective::on_debugger_command_done_signal (const UString &a_command,
     NEMIVER_CATCH
 }
 
+/// Callback function invoked once a breakpoint was set.
+///
+/// \param a_breaks the list of all breakpoints currently set in the inferior.
+///
+/// \param a_cookie a string passed to the IDebugger::set_breakpoint
+/// call that triggered this callback.
+///
 void
 DBGPerspective::on_debugger_breakpoint_set_signal
 (const std::pair<int, const IDebugger::Breakpoint&> &a,
@@ -2520,9 +2639,9 @@ DBGPerspective::on_debugger_breakpoints_list_signal
     // When the breakpoint is set, it
     // will send a 'cookie' along of the form
     // "initiallly-disabled#filename.cc#123"
-    if (a_cookie.find("initially-disabled") != UString::npos) {
-        UString::size_type start_of_file = a_cookie.find('#') + 1;
-        UString::size_type start_of_line = a_cookie.rfind('#') + 1;
+    if (a_cookie.find ("initially-disabled") != UString::npos) {
+        UString::size_type start_of_file = a_cookie.find ('#') + 1;
+        UString::size_type start_of_line = a_cookie.rfind ('#') + 1;
         UString file = a_cookie.substr (start_of_file,
                                         (start_of_line - 1) - start_of_file);
         int line = atoi
@@ -3379,6 +3498,39 @@ DBGPerspective::init_actions ()
             false
         },
         {
+            "JumpToCurrentLocationMenuItemAction",
+            nil_stock_id,
+            _("Jump to cursor"),
+            _("Jump to  the currently selected line"),
+            sigc::mem_fun (*this, &DBGPerspective::on_jump_to_current_location_action),
+            ActionEntry::DEFAULT,
+            "",
+            false
+        },
+        {
+            "JumpAndBreakToCurrentLocationMenuItemAction",
+            nil_stock_id,
+            _("Jump and stop to cursor"),
+            _("Sets a breakpoint to the current currently selected line and jump there"),
+            sigc::mem_fun (*this,
+                           &DBGPerspective::on_jump_and_break_to_current_location_action),
+            ActionEntry::DEFAULT,
+            "",
+            false
+        },
+        {
+            "JumpToLocationMenuItemAction",
+            nil_stock_id,
+            _("Jump to a given location"),
+            _("Select a given code location and jump there"),
+            sigc::mem_fun
+            (*this,
+             &DBGPerspective::on_jump_to_location_action),
+            ActionEntry::DEFAULT,
+            "<control>J",
+            false
+        },
+        {
             "ToggleBreakpointMenuItemAction",
             nil_stock_id,
             // Depending on the context we will want this string to be
@@ -4754,6 +4906,22 @@ DBGPerspective::get_contextual_menu ()
         workbench ().get_ui_manager ()->add_ui
             (m_priv->contextual_menu_merge_id,
              "/ContextualMenu",
+             "JumpToCurrentLocationMenuItem",
+             "JumpToCurrentLocationMenuItemAction",
+             Gtk::UI_MANAGER_AUTO,
+             false);
+
+        workbench ().get_ui_manager ()->add_ui
+            (m_priv->contextual_menu_merge_id,
+             "/ContextualMenu",
+             "JumpAndBreakToCurrentLocationMenuItem",
+             "JumpAndBreakToCurrentLocationMenuItemAction",
+             Gtk::UI_MANAGER_AUTO,
+             false);
+
+        workbench ().get_ui_manager ()->add_ui
+            (m_priv->contextual_menu_merge_id,
+             "/ContextualMenu",
              "StopMenuItem",
              "StopMenuItemAction",
              Gtk::UI_MANAGER_AUTO,
@@ -6688,6 +6856,157 @@ DBGPerspective::do_continue_until ()
     debugger ()->continue_to_position (file_path, current_line);
 }
 
+/// Jump (transfer execution of the inferior) to the location selected
+/// by the user in the source editor.
+void
+DBGPerspective::do_jump_to_current_location ()
+{
+    SourceEditor *editor = get_current_source_editor ();
+    THROW_IF_FAIL (editor);
+
+    int current_line = editor->current_line ();
+    UString file_path;
+    editor->get_file_name (file_path);
+    SourceLoc loc (file_path, current_line);
+    debugger ()->jump_to_position (loc, &null_default_slot);
+}
+
+///  Set a breakpoint to a given location and jump (transfer execution
+///  of the inferior) there.
+///
+///  \param a_location the location to set breakpoint and jump to
+void
+DBGPerspective::do_jump_and_break_to_location (const Loc &a_location)
+{
+#define JUMP_TO_LOC_AFTER_ENABLE_BP(LOC)                    \
+    debugger ()->enable_breakpoint                          \
+        (bp->number (),                                     \
+         sigc::bind                                         \
+         (sigc::mem_fun                                     \
+          (*this,                                           \
+           &DBGPerspective::jump_to_location),              \
+          (LOC)));
+
+#define JUMP_TO_LOC_AFTER_SET_BP(LOC)                   \
+    debugger ()->set_breakpoint                         \
+        (a_location,                                    \
+         /*a_condition=*/"",/*a_ignore_count=*/0,       \
+         sigc::bind                                     \
+         (sigc::mem_fun                                 \
+          (*this,                                       \
+           &DBGPerspective::on_break_before_jump),      \
+          (LOC)));
+
+    bool bp_enabled = false;
+    if (is_breakpoint_set_at_location (a_location,
+                                       bp_enabled)) {
+        if (bp_enabled) {
+            debugger ()->jump_to_position (a_location,
+                                           &null_default_slot);
+        } else {
+            const IDebugger::Breakpoint *bp =
+                get_breakpoint (a_location);
+            THROW_IF_FAIL (bp);
+            
+            switch (a_location.kind ()) {
+            case Loc::UNDEFINED_LOC_KIND:
+                THROW ("Should not be reached");
+
+            case Loc::SOURCE_LOC_KIND: {
+                SourceLoc loc
+                    (static_cast<const SourceLoc &> (a_location));
+                JUMP_TO_LOC_AFTER_ENABLE_BP (loc);
+            }
+                break;
+            case Loc::FUNCTION_LOC_KIND: {
+                FunctionLoc loc
+                    (static_cast<const FunctionLoc &> (a_location));
+                JUMP_TO_LOC_AFTER_ENABLE_BP (loc);
+            }
+                break;
+            case Loc::ADDRESS_LOC_KIND: {
+                AddressLoc loc
+                    (static_cast<const AddressLoc &> (a_location));
+                JUMP_TO_LOC_AFTER_ENABLE_BP (loc);
+            }
+                break;
+            }
+        }
+    } else {
+        switch (a_location.kind ()) {
+        case Loc::UNDEFINED_LOC_KIND:
+            THROW ("Should not be reached");
+
+        case Loc::SOURCE_LOC_KIND: {
+            SourceLoc loc
+                (static_cast<const SourceLoc &> (a_location));
+            JUMP_TO_LOC_AFTER_SET_BP (loc);
+        }
+            break;
+        case Loc::FUNCTION_LOC_KIND: {
+            FunctionLoc loc
+                (static_cast<const FunctionLoc &> (a_location));
+            JUMP_TO_LOC_AFTER_SET_BP (loc);
+        }
+            break;
+        case Loc::ADDRESS_LOC_KIND: {
+            AddressLoc loc
+                (static_cast<const AddressLoc &> (a_location));
+            JUMP_TO_LOC_AFTER_SET_BP (loc);
+        }
+            break;
+        }
+    }
+}
+
+/// Set a breakpoint to the location selected by the user in the
+/// source editor and jump (transfer execution of the inferior) there.
+void
+DBGPerspective::do_jump_and_break_to_current_location ()
+{
+    THROW_IF_FAIL (m_priv);
+    SourceEditor *editor = get_current_source_editor ();
+    THROW_IF_FAIL (editor);
+
+    SafePtr<const Loc> loc (editor->current_location ());
+    if (!loc) {
+        LOG_DD ("Got an empty location.  Getting out.");
+        return;
+    }
+    do_jump_and_break_to_location (*loc);
+}
+
+/// Jump (transfert execution of the inferior) to a given source
+/// location.  This is a callback for the
+/// IDebugger::breakpoint_set_signal signal.
+///
+/// \param a_loc the location to jump to.
+void
+DBGPerspective::jump_to_location (const map<int, IDebugger::Breakpoint>&,
+                                  const Loc &a_loc)
+{
+    debugger ()->jump_to_position (a_loc, &null_default_slot);
+}
+
+/// Jump (transfert execution of the inferior) to a given location
+/// that is specified by a dialog.  The dialog must have filled by the
+/// user prior to calling this function.
+///
+/// \param a_dialog the dialog that contains the location specified by
+/// the user.
+void
+DBGPerspective::jump_to_location_from_dialog (const SetJumpToDialog &a_dialog)
+{
+    SafePtr<const Loc> location (a_dialog.get_location ());
+    if (!location
+        || location->kind ()== Loc::UNDEFINED_LOC_KIND)
+        return;
+    if (a_dialog.get_break_at_location ())
+        do_jump_and_break_to_location (*location);
+    else
+        debugger ()->jump_to_position (*location, &null_default_slot);
+}
+
 void
 DBGPerspective::set_breakpoint ()
 {
@@ -6870,6 +7189,39 @@ DBGPerspective::append_breakpoints
         append_breakpoint (iter->second);
 }
 
+/// Return the breakpoint that was set at a given location.
+///
+/// \param a_location the location to consider
+///
+/// \return the breakpoint found at the given location, 0 if none was
+/// found.
+const IDebugger::Breakpoint*
+DBGPerspective::get_breakpoint (const Loc &a_location) const
+{
+    switch (a_location.kind ()) {
+    case Loc::UNDEFINED_LOC_KIND:
+        return false;
+    case Loc::SOURCE_LOC_KIND: {
+        const SourceLoc &loc =
+            static_cast<const SourceLoc&> (a_location);
+        return get_breakpoint (loc.file_path (), loc.line_number ());
+    }
+    case Loc::FUNCTION_LOC_KIND: {
+        // TODO: For now we cannot get a breakpoint set by function.
+        // For that we would need to be able to get the address at
+        // which a breakpoint set by function would be set to.
+        return false;
+    }
+    case Loc::ADDRESS_LOC_KIND: {
+        const AddressLoc &loc =
+            static_cast<const AddressLoc&> (a_location);
+        return get_breakpoint (loc.address ());
+    }
+    }
+    // Should not be reached.
+    return 0;
+}
+
 const IDebugger::Breakpoint*
 DBGPerspective::get_breakpoint (const UString &a_file_name,
                                 int a_line_num) const
@@ -7260,6 +7612,52 @@ DBGPerspective::delete_breakpoint (const Address &a_address)
     return delete_breakpoint (bp->number ());
 }
 
+/// Return true if a breakpoint was set at a given location.
+///
+/// \param a_location the location to consider
+///
+/// \return true if there was a breakpoint set at the given location
+bool
+DBGPerspective::is_breakpoint_set_at_location (const Loc &a_location,
+                                               bool &a_enabled)
+{
+    switch (a_location.kind ()) {
+    case Loc::UNDEFINED_LOC_KIND:
+        return false;
+    case Loc::SOURCE_LOC_KIND: {
+        const SourceLoc &loc =
+            static_cast<const SourceLoc&> (a_location);
+        return is_breakpoint_set_at_line (loc.file_path (),
+                                          loc.line_number (),
+                                          a_enabled);
+    }
+        break;
+    case Loc::FUNCTION_LOC_KIND:
+        // Grrr, for now we cannot know if a breakpoint was set at a
+        // function's entry point.
+        return false;
+        break;
+    case Loc::ADDRESS_LOC_KIND: {
+        const AddressLoc &loc =
+            static_cast<const AddressLoc&> (a_location);
+        return is_breakpoint_set_at_address (loc.address (),
+                                             a_enabled);
+    }
+        break;
+    }
+    // Should not be reached
+    return false;
+}
+
+/// Test whether if a breakpoint was set at a source location.
+///
+/// \param a_file_path the path of the file to consider
+///
+/// \param a_line_num the line number of the location to consider
+///
+/// \param a_enabled iff the function returns true, this boolean is
+/// set.  It's value is then either true if the breakpoint found at
+/// the given source location is enabled, false otherwise.
 bool
 DBGPerspective::is_breakpoint_set_at_line (const UString &a_file_path,
                                            int a_line_num,
@@ -7273,12 +7671,25 @@ DBGPerspective::is_breakpoint_set_at_line (const UString &a_file_path,
     return false;
 }
 
+/// Test whether if a breakpoint was set at a given address.
+///
+/// \param a_address the address to consider.
+///
+/// \param a_enabled iff the function returns true, this boolean is
+/// set.  It's value is then either true if the breakpoint found at
+/// the given address is enabled, false otherwise.
+///
+/// \return true if a breakpoint is set at the given address, false
+/// otherwise.
 bool
-DBGPerspective::is_breakpoint_set_at_address (const Address &a_address)
+DBGPerspective::is_breakpoint_set_at_address (const Address &a_address,
+                                              bool &a_enabled)
 {
     const IDebugger::Breakpoint *bp;
-    if ((bp = get_breakpoint (a_address)) != 0)
+    if ((bp = get_breakpoint (a_address)) != 0) {
+        a_enabled = bp->enabled ();
         return true;
+    }
     return false;
 }
 
@@ -7305,7 +7716,8 @@ void
 DBGPerspective::toggle_breakpoint (const Address &a_address)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
-    if (is_breakpoint_set_at_address (a_address)) {
+    bool enabled = false;
+    if (is_breakpoint_set_at_address (a_address, enabled)) {
         delete_breakpoint (a_address);
     } else {
         set_breakpoint (a_address, /*is_count_point=*/false);
diff --git a/src/persp/dbgperspective/nmv-set-jump-to-dialog.cc b/src/persp/dbgperspective/nmv-set-jump-to-dialog.cc
new file mode 100644
index 0000000..cc50c80
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-set-jump-to-dialog.cc
@@ -0,0 +1,465 @@
+/*
+ *This file is part of the Nemiver project
+ *
+ *Nemiver is free software; you can redistribute
+ *it and/or modify it under the terms of
+ *the GNU General Public License as published by the
+ *Free Software Foundation; either version 2,
+ *or (at your option) any later version.
+ *
+ *Nemiver is distributed in the hope that it will
+ *be useful, but WITHOUT ANY WARRANTY;
+ *without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *See the GNU General Public License for more details.
+ *
+ *You should have received a copy of the
+ *GNU General Public License along with Nemiver;
+ *see the file COPYING.
+ *If not, write to the Free Software Foundation,
+ *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *See COPYRIGHT file copyright information.
+ */
+#include <glib/gi18n.h>
+#include <sstream>
+#include "common/nmv-loc.h"
+#include "common/nmv-str-utils.h"
+#include "nmv-set-jump-to-dialog.h"
+#include "nmv-ui-utils.h"
+
+
+using namespace nemiver::common;
+using namespace nemiver::ui_utils;
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+class SetJumpToDialog::Priv
+{
+public:
+    Gtk::Entry *entry_function;
+    Gtk::Entry *entry_filename;
+    Gtk::Entry *entry_line;
+    Gtk::Entry *entry_address;
+    Gtk::RadioButton *radio_function_name;
+    Gtk::RadioButton *radio_source_location;
+    Gtk::RadioButton *radio_binary_location;
+    Gtk::CheckButton *check_break_at_destination;
+    Gtk::Button *okbutton;
+    UString current_file_name;
+
+    enum Mode
+    {
+        MODE_UNDEFINED = 0,
+        MODE_FUNCTION_NAME_LOCATION,
+        MODE_SOURCE_LOCATION,
+        MODE_BINARY_LOCATION
+    };
+
+    Priv (Gtk::Dialog &a_dialog,
+          const Glib::RefPtr<Gtk::Builder> &a_builder)
+        : entry_function (0),
+          entry_filename (0),
+          entry_line (0),
+          entry_address (0),
+          radio_function_name (0),
+          radio_source_location (0),
+          radio_binary_location (0),
+          check_break_at_destination (0),
+          okbutton (0)
+    {
+        a_dialog.set_default_response (Gtk::RESPONSE_OK);
+
+        entry_function =
+            get_widget_from_gtkbuilder<Gtk::Entry> (a_builder,
+                                                    "functionentry");
+        THROW_IF_FAIL (entry_function);
+        entry_function->signal_changed ().connect
+            (sigc::mem_fun (*this, &Priv::on_text_changed_signal));
+
+        entry_filename =
+            get_widget_from_gtkbuilder<Gtk::Entry> (a_builder,
+                                                    "filenameentry");
+        THROW_IF_FAIL (entry_filename);
+        entry_filename->signal_changed ().connect
+            (sigc::mem_fun (*this, &Priv::on_text_changed_signal));
+
+        entry_line =
+            get_widget_from_gtkbuilder<Gtk::Entry> (a_builder,
+                                                    "lineentry");
+        THROW_IF_FAIL (entry_line);
+        entry_line->signal_changed ().connect
+            (sigc::mem_fun (*this, &Priv::on_text_changed_signal));
+
+        entry_address =
+            get_widget_from_gtkbuilder<Gtk::Entry> (a_builder,
+                                                    "addressentry");
+        THROW_IF_FAIL (entry_address);
+        entry_address->signal_changed ().connect
+            (sigc::mem_fun (*this, &Priv::on_text_changed_signal));
+
+        radio_function_name =
+            get_widget_from_gtkbuilder<Gtk::RadioButton>
+            (a_builder, "functionnameradio");
+        THROW_IF_FAIL (radio_function_name);
+        radio_function_name->signal_clicked ().connect
+            (sigc::mem_fun (*this, &Priv::on_radiobutton_changed));
+
+        radio_source_location =
+            get_widget_from_gtkbuilder<Gtk::RadioButton>
+            (a_builder, "sourcelocationradio");
+        THROW_IF_FAIL (radio_source_location);
+        radio_source_location->signal_clicked ().connect
+            (sigc::mem_fun (*this, &Priv::on_radiobutton_changed));
+
+        radio_binary_location =
+            get_widget_from_gtkbuilder<Gtk::RadioButton>
+            (a_builder, "binarylocationradio");
+        THROW_IF_FAIL (radio_binary_location);
+        radio_binary_location->signal_clicked ().connect
+            (sigc::mem_fun (*this, &Priv::on_radiobutton_changed));
+
+        check_break_at_destination =
+            get_widget_from_gtkbuilder<Gtk::CheckButton>
+            (a_builder, "breakatdestinationcheck");
+        THROW_IF_FAIL (check_break_at_destination);
+
+        okbutton =
+            get_widget_from_gtkbuilder<Gtk::Button>
+            (a_builder, "okbutton");
+        THROW_IF_FAIL (okbutton);
+    }
+
+    /// Return the 'location setting mode' of the dialog.  I.e, it can
+    /// set either function name, source or binary address locations,
+    /// depending on the radio button that got selected by the user.
+    ///
+    /// \return the 'location setting mode' radio button selected by
+    /// the user.
+    Mode
+    mode () const
+    {
+        if (radio_function_name->get_active ())
+            return MODE_FUNCTION_NAME_LOCATION;
+        else if (radio_source_location->get_active ())
+            return MODE_SOURCE_LOCATION;
+        else if (radio_binary_location->get_active ())
+            return MODE_BINARY_LOCATION;
+        else
+            return MODE_UNDEFINED;
+    }
+
+    /// Set the 'location setting mode' of the dialog.
+    ///
+    /// \param a_mode the new mode to set.
+    void
+    mode (Mode a_mode)
+    {
+        switch (a_mode) {
+        case MODE_UNDEFINED:
+            THROW ("Unreachable code reached");
+            break;
+        case MODE_FUNCTION_NAME_LOCATION:
+            radio_function_name->set_active ();
+            break;
+        case MODE_SOURCE_LOCATION:
+            radio_source_location->set_active ();
+            break;
+        case MODE_BINARY_LOCATION:
+            radio_binary_location->set_active ();
+            break;
+        }
+    }
+
+    /// Return the location selected by the user using this dialog.
+    /// This is a pointer that needs to deleted by the caller.
+    ///
+    /// \return a pointer to the location selected by the user of the
+    /// dialog.  Must be deleted by the caller using the delete
+    /// operator.
+    Loc*
+    get_location () const
+    {
+        const Mode m = mode ();
+        switch (m) {
+        case MODE_UNDEFINED:
+            THROW ("Unreachable code reached");
+            break;
+        case MODE_FUNCTION_NAME_LOCATION: {
+            FunctionLoc *loc =
+                new FunctionLoc (entry_function->get_text ());
+            return loc;
+        }
+        case MODE_SOURCE_LOCATION: {
+            std::string path, line;
+            if (get_file_path_and_line_num (path, line)) {
+                SourceLoc *loc =
+                    new SourceLoc (path, atoi (line.c_str ()));
+                return loc;
+            }
+        }
+            break;
+        case MODE_BINARY_LOCATION: {
+            Address a (entry_address->get_text ());
+            AddressLoc *loc = new AddressLoc (a);
+            return loc;
+        }
+        } // end case
+
+        return 0;
+    }
+
+    /// Set a location in the dialog.  Depending on the type of
+    /// location, this function will Do The Right Thing, e.g,
+    /// selecting the right radio button etc
+    void
+    set_location (const Loc &a_loc)
+    {
+        switch (a_loc.kind ()) {
+        case Loc::UNDEFINED_LOC_KIND:
+            break;
+        case Loc::SOURCE_LOC_KIND: {
+            const SourceLoc &loc = static_cast<const SourceLoc&> (a_loc);
+            mode (MODE_SOURCE_LOCATION);
+            entry_filename->set_text (loc.file_path ());
+            std::ostringstream o;
+            o << loc.line_number ();
+            entry_line->set_text (o.str ());
+        }
+            break;
+        case Loc::FUNCTION_LOC_KIND: {
+            const FunctionLoc &loc = static_cast<const FunctionLoc&> (a_loc);
+            mode (MODE_FUNCTION_NAME_LOCATION);
+            entry_function->set_text (loc.function_name ());
+        }
+            break;
+        case Loc::ADDRESS_LOC_KIND: {
+            const AddressLoc &loc = static_cast<const AddressLoc&> (a_loc);
+            mode (MODE_BINARY_LOCATION);
+            std::ostringstream o;
+            o << loc.address ();
+            entry_address->set_text (o.str ());
+        }
+            break;
+        }
+    }
+
+    ///  Set the checkbox which semantic is to set a breakpoint at the
+    ///  jump location selected by the user.
+    ///
+    ///  \param a boolean meaning whether to select the "break at
+    ///  location" checkbox or not.
+    void
+    set_break_at_location (bool a)
+    {
+        check_break_at_destination->set_active (a);
+    }
+
+    /// Query whether the "break at location" checkbox is selected or
+    /// not.
+    ///
+    /// \return true if the "break at location" checkbox is selected,
+    /// false otherwise.
+    bool
+    get_break_at_location () const
+    {
+        return check_break_at_destination->get_active ();
+    }
+
+    /// Return the path/line number combo that the user entered in the
+    /// dialog, iff the dialog is in the "source location" mode.
+    ///
+    /// \param a_path the path of the source location.  This is set
+    /// iff the function returns true.
+    ///
+    /// \param a_line_num a string representing the line number of the
+    /// source location.  This is set iff the function returns true.
+    ///
+    /// \return true if the dialog is in source location mode and if
+    /// the user entered a file path or line number.
+    bool
+    get_file_path_and_line_num (std::string &a_path,
+                                std::string &a_line_num) const
+    {
+        if (entry_line->get_text ().empty ()) {
+            // Try to see if entry_filename contains a location string
+            // of the form "filename:number".
+            return str_utils::extract_path_and_line_num_from_location
+                (entry_filename->get_text ().raw (), a_path, a_line_num);
+        } else {
+            // Try to just get the file path from the entry_filename
+            // and line from entry_line.
+            //
+            // If entry_filename is empty then assume the user is
+            // referring to the file name being currently visited at
+            // the moment the dialog was being used.  That file name
+            // must have been set with
+            // SetJumpToDialog::set_current_file_name.
+            UString file_name;
+            if (entry_filename->get_text ().empty ())
+                file_name = current_file_name;
+            else
+                file_name = entry_filename->get_text ();
+
+            if (!file_name.empty ()
+                && atoi (entry_line->get_text ().c_str ())) {
+                a_path = file_name;
+                a_line_num = entry_line->get_text ().raw ();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /// Update the sensitivity of the OK button, depending on the
+    /// entries the user modified and what she typed in.
+    void
+    update_ok_button_sensitivity ()
+    {
+        THROW_IF_FAIL (entry_filename);
+        THROW_IF_FAIL (entry_line);
+        THROW_IF_FAIL (entry_function);
+        THROW_IF_FAIL (entry_address);
+        THROW_IF_FAIL (okbutton);
+
+        Mode m = mode ();
+        switch (m) {
+        case MODE_UNDEFINED:
+            break;
+        case MODE_SOURCE_LOCATION: {
+            string filename, line;
+            if (get_file_path_and_line_num (filename, line)
+                || atoi (entry_line->get_text ().c_str ()))
+                okbutton->set_sensitive (true);
+            else
+                okbutton->set_sensitive (false);
+        }
+        break;
+        case MODE_FUNCTION_NAME_LOCATION: {
+            if (!entry_function->get_text ().empty ())
+                okbutton->set_sensitive (true);
+            else
+                okbutton->set_sensitive (false);
+        }
+            break;
+        case MODE_BINARY_LOCATION: {
+            bool address_is_valid = false;
+            UString address = entry_address->get_text ();
+            // Validate the address
+            if (str_utils::string_is_number (address))
+                address_is_valid = true;
+            okbutton->set_sensitive (address_is_valid);
+        }
+            break;
+        default:
+            okbutton->set_sensitive (true);
+            break;
+        }
+    }
+
+    /// Set the name of the file being currently visited by the
+    /// editor.  This can be useful because it can save the user from
+    /// having to type in the name of the current file, and leave the
+    /// file name entry blank.
+    ///
+    /// \param a the name of the file name currently being visited
+    void
+    set_current_file_name (const UString &a)
+    {
+        current_file_name = a;
+    }
+
+    void
+    on_text_changed_signal ()
+    {
+        NEMIVER_TRY;
+
+        update_ok_button_sensitivity ();
+
+        NEMIVER_CATCH;
+    }
+
+    void
+    on_radiobutton_changed ()
+    {
+        NEMIVER_TRY;
+
+        Mode m = mode ();
+
+        entry_function->set_sensitive (m == MODE_FUNCTION_NAME_LOCATION);
+
+        entry_filename->set_sensitive (m == MODE_SOURCE_LOCATION);
+        entry_line->set_sensitive (m == MODE_SOURCE_LOCATION);
+
+        entry_address->set_sensitive (m == MODE_BINARY_LOCATION);
+
+        update_ok_button_sensitivity ();
+
+        NEMIVER_CATCH;
+    }
+};// end class SetJumpToDialog::Priv
+
+SetJumpToDialog::SetJumpToDialog (const UString &a_root_path)
+    : Dialog (a_root_path, "setjumptodialog.ui", "setjumptodialog")
+{
+    m_priv.reset (new Priv (widget (), gtkbuilder ()));
+}
+
+SetJumpToDialog::~SetJumpToDialog ()
+{
+}
+
+/// \return the location set by the user via the dialog
+const Loc*
+SetJumpToDialog::get_location () const
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->get_location ();
+}
+
+/// Set the location proprosed by the dialog.
+///
+/// \param a_loc the new location to set
+void
+SetJumpToDialog::set_location (const Loc &a_loc)
+{
+    THROW_IF_FAIL (m_priv);
+    
+    m_priv->set_location (a_loc);
+}
+
+/// Set or unset the "set break at location" check button
+///
+/// \param a if true, check the "set break at location" check button.
+/// Uncheck it otherwise.
+void
+SetJumpToDialog::set_break_at_location (bool a)
+{
+    THROW_IF_FAIL (m_priv);
+    m_priv->set_break_at_location (a);
+}
+
+/// Get the value of the "set break at location" check button.
+///
+/// \return true if the "set break at location" check button is
+/// checked, false otherwise.
+bool
+SetJumpToDialog::get_break_at_location () const
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->get_break_at_location ();
+}
+
+/// Set the name of the file being currently visited by the editor.
+/// This can be useful because it can save the user from having to
+/// type in the name of the current file, and leave the file name
+/// entry blank.
+///
+/// \param a the name of the file name currently being visited
+void
+SetJumpToDialog::set_current_file_name (const UString &a)
+{
+    THROW_IF_FAIL (m_priv);
+    m_priv->set_current_file_name (a);
+}
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/dbgperspective/nmv-set-jump-to-dialog.h b/src/persp/dbgperspective/nmv-set-jump-to-dialog.h
new file mode 100644
index 0000000..41da37f
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-set-jump-to-dialog.h
@@ -0,0 +1,58 @@
+//Author: Dodji Seketeli
+/*
+ *This file is part of the Nemiver project
+ *
+ *Nemiver is free software; you can redistribute
+ *it and/or modify it under the terms of
+ *the GNU General Public License as published by the
+ *Free Software Foundation; either version 2,
+ *or (at your option) any later version.
+ *
+ *Nemiver is distributed in the hope that it will
+ *be useful, but WITHOUT ANY WARRANTY;
+ *without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *See the GNU General Public License for more details.
+ *
+ *You should have received a copy of the
+ *GNU General Public License along with Nemiver;
+ *see the file COPYING.
+ *If not, write to the Free Software Foundation,
+ *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *See COPYRIGHT file copyright information.
+ */
+
+#ifndef __NEMIVER_SET_JUMP_TO_DIALOG_H__
+#define __NEMIVER_SET_JUMP_TO_DIALOG_H__
+
+#include "common/nmv-safe-ptr-utils.h"
+#include "nmv-dialog.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+namespace common {
+    class UString;
+    class Loc;
+}
+
+class SetJumpToDialog : public Dialog
+{
+    class Priv;
+    SafePtr<Priv> m_priv;
+
+ public:
+
+    SetJumpToDialog (const UString &a_resource_root_path);
+    virtual ~SetJumpToDialog ();
+
+    const common::Loc* get_location () const;
+    void set_location (const common::Loc&);
+    void set_break_at_location (bool);
+    bool get_break_at_location () const;
+    void set_current_file_name (const UString &);
+};
+
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif // __NEMIVER_JUMP_TO_DIALOG_H__
diff --git a/src/persp/dbgperspective/ui/Makefile.am b/src/persp/dbgperspective/ui/Makefile.am
index 496ce3a..2b42c3f 100644
--- a/src/persp/dbgperspective/ui/Makefile.am
+++ b/src/persp/dbgperspective/ui/Makefile.am
@@ -13,7 +13,8 @@ chooseoverloadsdialog.ui \
 remotetargetdialog.ui \
 globalvarsinspector.ui \
 callfunctiondialog.ui \
-watchpointdialog.ui
+watchpointdialog.ui  \
+setjumptodialog.ui
 
 uidir = @NEMIVER_PLUGINS_DIR@/$(PLUGIN_NAME)/ui
 ui_DATA = $(uifiles)
diff --git a/src/persp/dbgperspective/ui/setjumptodialog.ui b/src/persp/dbgperspective/ui/setjumptodialog.ui
new file mode 100644
index 0000000..203ff02
--- /dev/null
+++ b/src/persp/dbgperspective/ui/setjumptodialog.ui
@@ -0,0 +1,281 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkDialog" id="setjumptodialog">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Set location to jump to</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="default_width">300</property>
+    <property name="type_hint">dialog</property>
+    <property name="gravity">center</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child>
+          <object class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Jump to location:&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkAlignment" id="alignment1">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkTable" id="table1">
+                    <property name="visible">True</property>
+                    <property name="n_rows">8</property>
+                    <property name="n_columns">2</property>
+                    <property name="column_spacing">6</property>
+                    <property name="row_spacing">6</property>
+                    <child>
+                      <object class="GtkRadioButton" id="functionnameradio">
+                        <property name="label" translatable="yes">F_unction Name:</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="sourcelocationradio">
+                        <property name="label" translatable="yes">_Source Location:</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">functionnameradio</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="binarylocationradio">
+                        <property name="label" translatable="yes">_Binary Location:</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="use_underline">True</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">functionnameradio</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">5</property>
+                        <property name="bottom_attach">6</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Function:</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label3">
+                        <property name="visible">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">File name:</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label4">
+                        <property name="visible">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Line:</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">4</property>
+                        <property name="bottom_attach">5</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label5">
+                        <property name="visible">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Address:</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">6</property>
+                        <property name="bottom_attach">7</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="functionentry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">&#x25CF;</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="filenameentry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">&#x25CF;</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="lineentry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">&#x25CF;</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">4</property>
+                        <property name="bottom_attach">5</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="addressentry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">&#x25CF;</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">6</property>
+                        <property name="bottom_attach">7</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="breakatdestinationcheck">
+                        <property name="label" translatable="yes">Break at destination</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">7</property>
+                        <property name="bottom_attach">8</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="cancelbutton">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="okbutton">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">cancelbutton</action-widget>
+      <action-widget response="-5">okbutton</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/src/uicommon/nmv-source-editor.cc b/src/uicommon/nmv-source-editor.cc
index e3d6206..d27fe37 100644
--- a/src/uicommon/nmv-source-editor.cc
+++ b/src/uicommon/nmv-source-editor.cc
@@ -867,6 +867,37 @@ SourceEditor::current_column (int &a_col)
     m_priv->non_asm_ctxt.current_column = a_col;
 }
 
+/// Return a pointer to the current location selected by the user.
+///
+///  \return a pointer to an instance of Loc representing the location
+///  selected by the user.  If the user hasn't selected any location,
+///  then return 0.
+const Loc*
+SourceEditor::current_location () const
+{
+    BufferType type = get_buffer_type ();
+    switch (type) {
+    case BUFFER_TYPE_UNDEFINED:
+      break;
+    case BUFFER_TYPE_SOURCE: {
+        UString path;
+        get_path (path);
+        THROW_IF_FAIL (!path.empty ());
+	if (current_line () >= 0)
+	  return new SourceLoc (path, current_line ());
+    }
+      break;
+    case BUFFER_TYPE_ASSEMBLY: {
+        Address a;
+        if (current_address (a))
+	  return new AddressLoc (a);
+    }
+      break;
+    }
+
+    return 0;
+}
+
 bool
 SourceEditor::move_where_marker_to_line (int a_line, bool a_do_scroll)
 {
diff --git a/src/uicommon/nmv-source-editor.h b/src/uicommon/nmv-source-editor.h
index bbf1442..13132e6 100644
--- a/src/uicommon/nmv-source-editor.h
+++ b/src/uicommon/nmv-source-editor.h
@@ -35,6 +35,7 @@
 #include "common/nmv-address.h"
 #include "common/nmv-range.h"
 #include "common/nmv-asm-instr.h"
+#include "common/nmv-loc.h"
 
 using gtksourceview::SourceView;
 using gtksourceview::SourceBuffer;
@@ -42,6 +43,7 @@ using Gtk::VBox;
 using nemiver::common::SafePtr;
 using nemiver::common::UString;
 using nemiver::common::Address;
+using nemiver::common::Loc;
 using std::list;
 using std::map;
 
@@ -82,6 +84,7 @@ public:
     int current_line () const;
     void current_line (int a_line);
     int current_column () const;
+    const Loc* current_location () const;
     void current_column (int &a_col);
     bool move_where_marker_to_line (int a_line, bool a_do_scroll = true);
     void unset_where_marker ();



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