[nemiver] New Layout Manager and 3 additionals new layouts



commit e65f0265f514f6f12946ca58815230efb72260c1
Author: Fabien Parent <parent f gmail com>
Date:   Sun Jul 24 16:38:56 2011 +0200

    New Layout Manager and 3 additionals new layouts
    
    	* configure.ac: Add directives to enable/disable the building of the
    	dynamic layout.
    	* data/schemas/gconf/nemiver-dbgperspective.schemas: Add new configuration
    	keys for the new layouts.
    	* data/schemas/gsettings/org.nemiver.gschema.xml: Likewise
    	* src/confmgr/nmv-conf-keys.h: Likewise
    	* src/confmgr/nmv-gconf-keys-defs.cc: Likewise
    	* src/confmgr/nmv-gsettings-keys-defs.c: Likewise
    	* src/persp/dbgperspective/Makefile.am: Add new source files
    	* src/persp/dbgperspective/nmv-dbg-perspective-default-layout.cc: New API
    	* src/persp/dbgperspective/nmv-dbg-perspective-default-layout.h: Likewise
    	* src/persp/dbgperspective/nmv-dbg-perspective-dynamic-layout.cc: Likewise
    	* src/persp/dbgperspective/nmv-dbg-perspective-dynamic-layout.h: Likewise
    	* src/persp/dbgperspective/nmv-dbg-perspective-two-pane-layout.cc: Likewise
    	* src/persp/dbgperspective/nmv-dbg-perspective-two-pane-layout.h: Likewise
    	* src/persp/dbgperspective/nmv-dbg-perspective-wide-layout.cc: Likewise
    	* src/persp/dbgperspective/nmv-dbg-perspective-wide-layout.h: Likewise.
    	* src/persp/dbgperspective/nmv-dbg-perspective.cc
    	(DBGPerspective::on_layout_changed): New API
    	(DBGPerspective::init_perspective_menu_entries): Removed
    	(DBGPerspective::register_layouts): New API
    	(DBGPerspective::get_source_view_widget): New API
    	(DBGPerspective::set_show_context_view): Removed
    	(DBGPerspective::set_show_terminal_view): Likewise
    	(DBGPerspective::set_show_breakpoints_view): Likewise
    	(DBGPerspective::set_show_registers_view): Likewise
    	(DBGPerspective::set_show_memory_view): Likewise
    	(DBGPerspective::activate_status_view): Removed. Implemented in each Layout.
    	(DBGPerspective::Priv::Priv):
    	(DBGPerspective::Priv::layout): New API
    	(DBGPerspective::on_shutdown_signal): Call the layout's save_configuration
    	method.
    	(DBGPerspective::on_debugger_running_signal): Check pointer before using it
    	(DBGPerspective::on_activate_context_view): Use the new Layout Manager API
    	(DBGPerspective::on_activate_target_terminal_view): Likewise
    	(DBGPerspective::on_activate_breakpoints_view): Likewise
    	(DBGPerspective::on_activate_registers_view): Likewise
    	(DBGPerspective::on_activate_memory_view): Likewise
    	(DBGPerspective::init_actions): Use Renamed ViewsIndex's elements.
    	(DBGPerspective::init_body): Move status views initialization into the new
    	Layout API.
    	(DBGPerspective::init_signals): Connect signal
    	to DBGPerspective::on_layout_changed when the layout has changed.
    	(DBGPerspective::bring_source_as_current): Check pointer before using it.
    	(DBGPerspective::do_init): Call register_layouts to initialize the layout
    	manager.
    	(DBGPerspective::get_body): Use the Layout Manager to get the perspective's
    	body.
    	(DBGPerspective::edit_workbench_menu): Remove comment
    	(DBGPerspective::update_file_maps): Check pointer before using it.
    	(DBGPerspective::edit_preferences): Adapt to the new PreferencesDialog's
    	constructor prototype.
    	(DBGPerspective::layout_changed_signal): New API
    	(DBGPerspective::add_views_to_layout): New API
    	* src/persp/dbgperspective/nmv-dbg-perspective.h
    	(DBGPerspective::get_source_view_widget): New API
    	(DBGPerspective::get_conf_mgr): Add the method to the interface
    	(DBGPerspective::layout_changed_signal): New API
    	* src/persp/dbgperspective/nmv-preferences-dialog.cc
    	(PreferencesDialog::Priv::Priv): Take the Perspective and the LayoutManager
    	as parameters instead of a Workbench.
    	(PreferencesDialog::Priv::init): Add the LayoutSelector widget to the
    	preferences dialog.
    	(PreferencesDialog::Priv::conf_manager): Use the IPerspective to get the
    	configuration manager instead of the workbench.
    	(PreferencesDialog::PreferencesDialog): Take the Perspective and
    	the LayoutManager as parameters instead of a Workbench.
    	* src/persp/dbgperspective/nmv-preferences-dialog.h
    	(PreferencesDialog::PreferencesDialog): Take the Perspective and
    	the LayoutManager as parameters instead of a Workbench.
    	* src/persp/dbgperspective/ui/Makefile.am: Remove bodycontainer.ui file
    	* src/persp/dbgperspective/ui/bodycontainer.ui: Removed
    	* src/persp/dbgperspective/ui/preferencesdialog.ui: Add Layout tab
    	* src/persp/nmv-i-perspective.h: Add a signal when the layout changed.
    	* src/uicommon/Makefile.am: Add new source files and add new include
    	directories.
    	* src/uicommon/nmv-layout-manager.cc: New API
    	* src/uicommon/nmv-layout-manager.h: Likewise
    	* src/uicommon/nmv-layout-selector.cc: Likewise
    	* src/uicommon/nmv-layout-selector.h: Likewise
    	* src/uicommon/nmv-layout.h: Likewise
    	* src/workbench/nmv-workbench.cc
    	(Workbench::on_perspective_body_changed_signal): New API
    	(Workbench::disconnect_all_perspective_signals): New API
    	(Workbench::~Workbench): Disconnect perspectives layout_changed_signal
    	(Workbench::do_init): Attach the signal 'layout_changed_signal' when
    	the layout changed to the Workbench::on_perspective_layout_changed_signal
    	method.

 configure.ac                                       |   22 +-
 data/schemas/gconf/nemiver-dbgperspective.schemas  |   52 +++-
 data/schemas/gsettings/org.nemiver.gschema.xml     |   30 ++-
 src/confmgr/nmv-conf-keys.h                        |    6 +-
 src/confmgr/nmv-gconf-keys-defs.cc                 |   13 +-
 src/confmgr/nmv-gsettings-keys-defs.cc             |   11 +-
 src/persp/dbgperspective/Makefile.am               |   20 +-
 .../nmv-dbg-perspective-default-layout.cc          |  211 ++++++++++
 .../nmv-dbg-perspective-default-layout.h           |   71 ++++
 .../nmv-dbg-perspective-dynamic-layout.cc          |  297 +++++++++++++
 .../nmv-dbg-perspective-dynamic-layout.h           |   71 ++++
 .../nmv-dbg-perspective-two-pane-layout.cc         |  253 ++++++++++++
 .../nmv-dbg-perspective-two-pane-layout.h          |   71 ++++
 .../nmv-dbg-perspective-wide-layout.cc             |  208 ++++++++++
 .../nmv-dbg-perspective-wide-layout.h              |   71 ++++
 src/persp/dbgperspective/nmv-dbg-perspective.cc    |  435 +++++++-------------
 src/persp/dbgperspective/nmv-dbg-perspective.h     |   24 ++
 src/persp/dbgperspective/nmv-preferences-dialog.cc |   35 ++-
 src/persp/dbgperspective/nmv-preferences-dialog.h  |    6 +-
 src/persp/dbgperspective/ui/Makefile.am            |    3 +-
 src/persp/dbgperspective/ui/bodycontainer.ui       |   46 --
 src/persp/dbgperspective/ui/preferencesdialog.ui   |   23 +
 src/persp/nmv-i-perspective.h                      |    4 +
 src/uicommon/Makefile.am                           |   12 +-
 src/uicommon/nmv-layout-manager.cc                 |  157 +++++++
 src/uicommon/nmv-layout-manager.h                  |   74 ++++
 src/uicommon/nmv-layout-selector.cc                |  193 +++++++++
 src/uicommon/nmv-layout-selector.h                 |   58 +++
 src/uicommon/nmv-layout.h                          |  109 +++++
 src/workbench/nmv-workbench.cc                     |   40 ++
 30 files changed, 2254 insertions(+), 372 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index b2cab9d..0a6722d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,8 @@ LIBGIOMM_WITH_GSETTINGS_VERSION=2.25.1
 AC_SUBST([GIOMM_WITH_GSETTINGS_VERSION])
 GSETTINGS_DESKTOP_SCHEMAS=0.0.1
 AC_SUBST([GSETTINGS_DESKTOP_SCHEMAS])
+LIBGDLMM_VERSION=3.0
+AC_SUBST([LIBGDLMM_VERSION])
 
 dnl *********************
 dnl Checks for programs.
@@ -178,6 +180,19 @@ fi
 AM_CONDITIONAL(BUILD_MEMORYVIEW, test x$ENABLE_MEMORYVIEW = xyes)
 
 
+AC_ARG_ENABLE(dynamiclayout,
+              AS_HELP_STRING([--enable-dynamiclayout=yes|no],
+                             [enable the dynamic layout (default is yes)]),
+              ENABLE_DYNAMICLAYOUT=$enableval,
+              [PKG_CHECK_EXISTS([gdlmm-3.0 >= $LIBGDLMM_VERSION], [ENABLE_DYNAMICLAYOUT=yes], [ENABLE_DYNAMICLAYOUT=no])])
+if test x$ENABLE_DYNAMICLAYOUT = xyes ; then
+    AC_DEFINE([WITH_DYNAMICLAYOUT], 1, [compile the dynamic layout])
+else
+    ENABLE_DYNAMICLAYOUT=no
+fi
+AM_CONDITIONAL(BUILD_DYNAMICLAYOUT, test x$ENABLE_DYNAMICLAYOUT = xyes)
+
+
 ENABLE_DEBUG=yes
 AC_ARG_ENABLE(debug,
               AS_HELP_STRING([--enable-debug=yes|no],
@@ -266,6 +281,10 @@ if test x$ENABLE_MEMORYVIEW = xyes ; then
     DEP_MEMORYVIEW="gtkhex-3 >= $GTKHEX_VERSION"
 fi
 
+if test x$ENABLE_DYNAMICLAYOUT = xyes ; then
+    DEP_DYNAMICLAYOUT="gdlmm-3.0 >= $LIBGDLMM_VERSION"
+fi
+
 dnl *******************
 dnl Configuration Manager
 dnl *******************
@@ -337,7 +356,7 @@ dnl library dependencies for the nemiver debug perspective plugin
 DEP_PERSP="gtksourceviewmm-3.0 >= $LIBGTKSOURCEVIEWMM_VERSION \
            vte-2.90 >= $LIBVTE_VERSION"
 
-PKG_CHECK_MODULES(NEMIVERDBGPERSP, $DEP_UICOMMON $DEP_VFS $DEP_PERSP $DEP_MEMORYVIEW)
+PKG_CHECK_MODULES(NEMIVERDBGPERSP, $DEP_UICOMMON $DEP_VFS $DEP_PERSP $DEP_MEMORYVIEW $DEP_DYNAMICLAYOUT)
 NEMIVERDBGPERSP_LIBS="$NEMIVERDBGPERSP_LIBS $CPPUNIT_LIBS"
 NEMIVERDBGPERSP_CFLAGS="$NEMIVERDBGPERSP_CFLAGS $CPPUNIT_CFLAGS"
 
@@ -495,6 +514,7 @@ AC_MSG_NOTICE([
     Enable verbose debug messages   : ${ENABLE_DEBUG}
     Enable workbench                : ${ENABLE_WORKBENCH}
     Enable memory view              : ${ENABLE_MEMORYVIEW} (requires gtkhex > $GTKHEX_VERSION)
+    Enable dynamic layout           : ${ENABLE_DYNAMICLAYOUT} (requires gdlmm > $LIBGDLMM_VERSION)
     Configuration Manager           : ${CONF_MGR}
     Enable symbols visibility ctrl  : ${ENABLE_GCC_SYMBOLS_VISIBILITY}
     Maintainer mode                 : ${USER_MAINTAINER_MODE}
diff --git a/data/schemas/gconf/nemiver-dbgperspective.schemas b/data/schemas/gconf/nemiver-dbgperspective.schemas
index 61e7cae..a0a357c 100644
--- a/data/schemas/gconf/nemiver-dbgperspective.schemas
+++ b/data/schemas/gconf/nemiver-dbgperspective.schemas
@@ -2,6 +2,17 @@
 <gconfschemafile>
   <schemalist>
     <schema>
+      <key>/schemas/apps/nemiver/dbgperspective/layout</key>
+      <applyto>/apps/nemiver/dbgperspective/layout</applyto>
+      <owner>nemiver</owner>
+      <type>string</type>
+      <default>default-layout</default>
+      <locale name="C">
+	<short>Layout of the perspective</short>
+	<long>The layout that is loaded by the debugging perspective</long>
+      </locale>
+    </schema>
+    <schema>
       <key>/schemas/apps/nemiver/dbgperspective/source-search-dirs</key>
       <applyto>/apps/nemiver/dbgperspective/source-search-dirs</applyto>
       <owner>nemiver</owner>
@@ -136,14 +147,47 @@
       </locale>
     </schema>
     <schema>
-      <key>/schemas/apps/nemiver/dbgperspective/status-pane-location</key>
-      <applyto>/apps/nemiver/dbgperspective/status-pane-location</applyto>
+      <key>/schemas/apps/nemiver/dbgperspective/default-layout-status-pane-location</key>
+      <applyto>/apps/nemiver/dbgperspective/default-layout-status-pane-location</applyto>
+      <owner>nemiver</owner>
+      <type>int</type>
+      <default>-1</default>
+      <locale name="C">
+	<short>The location of the status pane for the default layout</short>
+	<long>The location of the status pane for the default layout</long>
+      </locale>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nemiver/dbgperspective/wide-layout-status-pane-location</key>
+      <applyto>/apps/nemiver/dbgperspective/wide-layout-status-pane-location</applyto>
+      <owner>nemiver</owner>
+      <type>int</type>
+      <default>-1</default>
+      <locale name="C">
+        <short>The location of the status pane for the wide layout</short>
+        <long>The location of the status pane for the wide layout</long>
+      </locale>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nemiver/dbgperspective/two-pane-layout-hpane-location</key>
+      <applyto>/apps/nemiver/dbgperspective/two-pane-layout-hpane-location</applyto>
+      <owner>nemiver</owner>
+      <type>int</type>
+      <default>-1</default>
+      <locale name="C">
+        <short>The location of the horizontal status pane for the two-pane layout</short>
+        <long>The location of the horizontal status pane for the two-pane layout</long>
+      </locale>
+    </schema>
+        <schema>
+      <key>/schemas/apps/nemiver/dbgperspective/two-pane-layout-vpane-location</key>
+      <applyto>/apps/nemiver/dbgperspective/two-pane-layout-vpane-location</applyto>
       <owner>nemiver</owner>
       <type>int</type>
       <default>-1</default>
       <locale name="C">
-	<short>The location of the status pane</short>
-	<long>The location of the status pane</long>
+        <short>The location of the vertical status pane for the two-pane layout</short>
+        <long>The location of the vertical status pane for the two-pane layout</long>
       </locale>
     </schema>
     <schema>
diff --git a/data/schemas/gsettings/org.nemiver.gschema.xml b/data/schemas/gsettings/org.nemiver.gschema.xml
index ff491bb..603d87b 100644
--- a/data/schemas/gsettings/org.nemiver.gschema.xml
+++ b/data/schemas/gsettings/org.nemiver.gschema.xml
@@ -1,5 +1,11 @@
 <schemalist>
   <schema id="org.nemiver" path="/apps/nemiver/">
+    <key name="dbg-perspective-layout" type="s">
+      <default>'default-layout'</default>
+      <summary>Layout of the perspective</summary>
+      <description>The layout that is loaded by the debugging perspective</description>
+    </key>
+
     <key name="source-search-dirs" type="s">
       <default>'.'</default>
       <summary>source directory dirs</summary>
@@ -72,10 +78,28 @@
       <description>The minimum height of the status widget.</description>
     </key>
 
-    <key name="status-pane-location" type="i">
+    <key name="default-layout-pane-location" type="i">
+      <default>-1</default>
+      <summary>The location of the status pane for the default layout</summary>
+      <description>The location of the status pane for the default layout</description>
+    </key>
+
+    <key name="wide-layout-pane-location" type="i">
+      <default>-1</default>
+      <summary>The location of the status pane for the wide layout</summary>
+      <description>The location of the status pane for the wide layout</description>
+    </key>
+
+    <key name="two-pane-layout-vpane-location" type="i">
+      <default>-1</default>
+      <summary>The location of the vertical status pane for the two-pane layout</summary>
+      <description>The location of the vertical status pane for the two-pane layout</description>
+    </key>
+
+    <key name="two-pane-layout-hpane-location" type="i">
       <default>-1</default>
-      <summary>The location of the status pane</summary>
-      <description>The location of the status pane.</description>
+      <summary>The location of the horizontal status pane for the two-pane layout</summary>
+      <description>The location of the horizontalstatus pane for the two-pane layout</description>
     </key>
 
     <key name="debugger-engine-dynmod" type="s">
diff --git a/src/confmgr/nmv-conf-keys.h b/src/confmgr/nmv-conf-keys.h
index d885377..ba33f1d 100644
--- a/src/confmgr/nmv-conf-keys.h
+++ b/src/confmgr/nmv-conf-keys.h
@@ -48,7 +48,10 @@ extern const char* CONF_KEY_CUSTOM_FONT_NAME;
 extern const char* CONF_KEY_USE_LAUNCH_TERMINAL;
 extern const char* CONF_KEY_STATUS_WIDGET_MINIMUM_WIDTH;
 extern const char* CONF_KEY_STATUS_WIDGET_MINIMUM_HEIGHT;
-extern const char* CONF_KEY_STATUS_PANE_LOCATION;
+extern const char* CONF_KEY_DEFAULT_LAYOUT_STATUS_PANE_LOCATION;
+extern const char* CONF_KEY_WIDE_LAYOUT_STATUS_PANE_LOCATION;
+extern const char* CONF_KEY_TWO_PANE_LAYOUT_STATUS_HPANE_LOCATION;
+extern const char* CONF_KEY_TWO_PANE_LAYOUT_STATUS_VPANE_LOCATION;
 extern const char* CONF_KEY_DEBUGGER_ENGINE_DYNMOD_NAME;
 extern const char* CONF_KEY_EDITOR_STYLE_SCHEME;
 extern const char* CONF_KEY_ASM_STYLE_PURE;
@@ -58,6 +61,7 @@ extern const char* CONF_KEY_FOLLOW_FORK_MODE;
 extern const char* CONF_KEY_DISASSEMBLY_FLAVOR;
 extern const char* CONF_KEY_CONTEXT_PANE_LOCATION;
 extern const char* CONF_KEY_NEMIVER_CALLSTACK_EXPANSION_CHUNK;
+extern const char* CONF_KEY_DBG_PERSPECTIVE_LAYOUT;
 
 extern const char* CONF_KEY_NEMIVER_WINDOW_WIDTH;
 extern const char* CONF_KEY_NEMIVER_WINDOW_HEIGHT;
diff --git a/src/confmgr/nmv-gconf-keys-defs.cc b/src/confmgr/nmv-gconf-keys-defs.cc
index 38af25f..2df0e8d 100644
--- a/src/confmgr/nmv-gconf-keys-defs.cc
+++ b/src/confmgr/nmv-gconf-keys-defs.cc
@@ -60,8 +60,14 @@ const char* CONF_KEY_STATUS_WIDGET_MINIMUM_WIDTH =
                 "/apps/nemiver/dbgperspective/status-widget-minimum-width";
 const char* CONF_KEY_STATUS_WIDGET_MINIMUM_HEIGHT =
                 "/apps/nemiver/dbgperspective/status-widget-minimum-height";
-const char* CONF_KEY_STATUS_PANE_LOCATION =
-                "/apps/nemiver/dbgperspective/status-pane-location";
+const char* CONF_KEY_DEFAULT_LAYOUT_STATUS_PANE_LOCATION =
+                "/apps/nemiver/dbgperspective/default-layout-status-pane-location";
+const char* CONF_KEY_WIDE_LAYOUT_STATUS_PANE_LOCATION =
+                "/apps/nemiver/dbgperspective/wide-layout-status-pane-location";
+const char* CONF_KEY_TWO_PANE_LAYOUT_STATUS_VPANE_LOCATION =
+                "/apps/nemiver/dbgperspective/two-pane-layout-vpane-location";
+const char* CONF_KEY_TWO_PANE_LAYOUT_STATUS_HPANE_LOCATION =
+                "/apps/nemiver/dbgperspective/two-pane-layout-hpane-location";
 const char* CONF_KEY_DEBUGGER_ENGINE_DYNMOD_NAME =
                 "/apps/nemiver/dbgperspective/debugger-engine-dynmod";
 const char* CONF_KEY_EDITOR_STYLE_SCHEME =
@@ -80,7 +86,8 @@ const char* CONF_KEY_CONTEXT_PANE_LOCATION =
                 "/apps/nemiver/dbgperspective/context-pane-location";
 const char* CONF_KEY_NEMIVER_CALLSTACK_EXPANSION_CHUNK =
                 "/apps/nemiver/dbgperspective/callstack-expansion-chunk";
-
+const char* CONF_KEY_DBG_PERSPECTIVE_LAYOUT =
+                "/apps/nemiver/dbgperspective/layout";
 
 /* Workbench */
 const char* CONF_KEY_NEMIVER_WINDOW_WIDTH =
diff --git a/src/confmgr/nmv-gsettings-keys-defs.cc b/src/confmgr/nmv-gsettings-keys-defs.cc
index cf0e184..1ce2756 100644
--- a/src/confmgr/nmv-gsettings-keys-defs.cc
+++ b/src/confmgr/nmv-gsettings-keys-defs.cc
@@ -49,7 +49,14 @@ const char* CONF_KEY_STATUS_WIDGET_MINIMUM_WIDTH =
                 "status-widget-minimum-width";
 const char* CONF_KEY_STATUS_WIDGET_MINIMUM_HEIGHT =
                 "status-widget-minimum-height";
-const char* CONF_KEY_STATUS_PANE_LOCATION = "status-pane-location";
+const char* CONF_KEY_DEFAULT_LAYOUT_STATUS_PANE_LOCATION =
+                "default-layout-pane-location";
+const char* CONF_KEY_WIDE_LAYOUT_STATUS_PANE_LOCATION =
+                "wide-layout-pane-location";
+const char* CONF_KEY_TWO_PANE_LAYOUT_STATUS_VPANE_LOCATION =
+                "two-pane-layout-vpane-location";
+const char* CONF_KEY_TWO_PANE_LAYOUT_STATUS_HPANE_LOCATION =
+                "two-pane-layout-hpane-location";
 const char* CONF_KEY_DEBUGGER_ENGINE_DYNMOD_NAME = "debugger-engine-dynmod";
 const char* CONF_KEY_EDITOR_STYLE_SCHEME = "editor-style-scheme";
 const char* CONF_KEY_ASM_STYLE_PURE = "asm-style-pure";
@@ -60,7 +67,7 @@ const char* CONF_KEY_DISASSEMBLY_FLAVOR = "disassembly-flavor";
 const char* CONF_KEY_CONTEXT_PANE_LOCATION = "context-pane-location";
 const char* CONF_KEY_NEMIVER_CALLSTACK_EXPANSION_CHUNK =
                 "callstack-expansion-chunk";
-
+const char* CONF_KEY_DBG_PERSPECTIVE_LAYOUT = "dbg-perspective-layout";
 
 /* Workbench */
 const char* CONF_KEY_NEMIVER_WINDOW_WIDTH = "window-width";
diff --git a/src/persp/dbgperspective/Makefile.am b/src/persp/dbgperspective/Makefile.am
index 618f146..7852432 100644
--- a/src/persp/dbgperspective/Makefile.am
+++ b/src/persp/dbgperspective/Makefile.am
@@ -67,7 +67,21 @@ $(h)/nmv-vars-treeview.cc \
 $(h)/nmv-call-function-dialog.h \
 $(h)/nmv-call-function-dialog.cc \
 $(h)/nmv-set-jump-to-dialog.h \
-$(h)/nmv-set-jump-to-dialog.cc
+$(h)/nmv-set-jump-to-dialog.cc \
+$(h)/nmv-dbg-perspective-default-layout.cc \
+$(h)/nmv-dbg-perspective-default-layout.h \
+$(h)/nmv-dbg-perspective-two-pane-layout.cc \
+$(h)/nmv-dbg-perspective-two-pane-layout.h \
+$(h)/nmv-dbg-perspective-wide-layout.cc \
+$(h)/nmv-dbg-perspective-wide-layout.h
+
+if BUILD_DYNAMICLAYOUT
+dynamiclayout_sources = \
+$(h)/nmv-dbg-perspective-dynamic-layout.cc \
+$(h)/nmv-dbg-perspective-dynamic-layout.h
+else
+dynamiclayout_sources =
+endif
 
 if BUILD_MEMORYVIEW
 memoryview_sources = \
@@ -77,7 +91,8 @@ else
 memoryview_sources =
 endif
 
-libdbgperspectiveplugin_la_SOURCES=$(sources) $(memoryview_sources)
+libdbgperspectiveplugin_la_SOURCES=$(sources) $(memoryview_sources) \
+$(dynamiclayout_sources)
 libdbgperspectiveplugin_la_LDFLAGS= -module -avoid-version -Wl,--as-needed
 libdbgperspectiveplugin_la_LIBADD= \
 @NEMIVERDBGPERSP_LIBS@ \
@@ -93,4 +108,3 @@ INCLUDES= NEMIVERDBGPERSP_CFLAGS@ -DENABLE_NLS=1 -DDATADIR=\"${datadir}\" \
 -I$(abs_top_srcdir)/src/workbench \
 -I$(abs_top_srcdir)/src/persp \
 -I$(abs_top_srcdir)/src/dbgperspective
-
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective-default-layout.cc b/src/persp/dbgperspective/nmv-dbg-perspective-default-layout.cc
new file mode 100644
index 0000000..ba5a7c5
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-dbg-perspective-default-layout.cc
@@ -0,0 +1,211 @@
+//Author: Fabien Parent
+/*
+ *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 "config.h"
+#include "common/nmv-safe-ptr.h"
+#include "nmv-dbg-perspective.h"
+#include "nmv-dbg-perspective-default-layout.h"
+#include "nmv-ui-utils.h"
+#include "nmv-conf-keys.h"
+
+#include <gtkmm/notebook.h>
+#include <glib/gi18n.h>
+
+using namespace std;
+using namespace nemiver::ui_utils;
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+/// \brief Default Nemiver's Layout
+///
+/// This is the default nemiver's layout.
+/// Every debugging panels are inside a single notebook which is displayed
+/// below the sourceview notebook.
+struct DBGPerspectiveDefaultLayout::Priv {
+    SafePtr<Gtk::Paned> body_main_paned;
+    SafePtr<Gtk::Notebook> statuses_notebook;
+    map<int, Gtk::Widget&> views;
+    IDBGPerspective &dbg_perspective;
+
+    Priv (IDBGPerspective &a_dbg_perspective) :
+        dbg_perspective (a_dbg_perspective)
+    {
+    }
+}; //end struct DBGPerspectiveDefaultLayout::Priv
+
+Gtk::Widget*
+DBGPerspectiveDefaultLayout::widget () const
+{
+    return m_priv->body_main_paned.get ();
+}
+
+DBGPerspectiveDefaultLayout::DBGPerspectiveDefaultLayout ()
+{
+}
+
+DBGPerspectiveDefaultLayout::~DBGPerspectiveDefaultLayout ()
+{
+    LOG_D ("deleted", "destructor-domain");
+}
+
+void
+DBGPerspectiveDefaultLayout::do_lay_out (IPerspective &a_perspective)
+{
+    m_priv.reset (new Priv (dynamic_cast<IDBGPerspective&> (a_perspective)));
+    THROW_IF_FAIL (m_priv);
+
+    m_priv->body_main_paned.reset (new Gtk::VPaned);
+    m_priv->body_main_paned->set_position (350);
+
+    // set the position of the status pane to the last saved position
+    IConfMgr &conf_mgr = m_priv->dbg_perspective.get_conf_mgr ();
+    int pane_location = -1; // don't specifically set a location
+                            // if we can't read the last location from gconf
+    NEMIVER_TRY
+    conf_mgr.get_key_value (CONF_KEY_DEFAULT_LAYOUT_STATUS_PANE_LOCATION,
+                            pane_location);
+    NEMIVER_CATCH
+
+    if (pane_location >= 0) {
+        m_priv->body_main_paned->set_position (pane_location);
+    }
+
+    m_priv->statuses_notebook.reset (new Gtk::Notebook);
+    m_priv->statuses_notebook->set_tab_pos (Gtk::POS_BOTTOM);
+
+    m_priv->body_main_paned->pack2 (*m_priv->statuses_notebook);
+    m_priv->body_main_paned->pack1
+        (m_priv->dbg_perspective.get_source_view_widget (), true, true);
+
+    int width=100, height=70;
+
+    NEMIVER_TRY
+    conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_WIDTH, width);
+    conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_HEIGHT, height);
+    NEMIVER_CATCH
+
+    LOG_DD ("setting status widget min size: width: "
+            << width
+            << ", height: "
+            << height);
+    m_priv->statuses_notebook->set_size_request (width, height);
+    m_priv->body_main_paned->show_all ();
+}
+
+void
+DBGPerspectiveDefaultLayout::do_init ()
+{
+}
+
+void
+DBGPerspectiveDefaultLayout::do_cleanup_layout ()
+{
+    m_priv.reset ();
+}
+
+const UString&
+DBGPerspectiveDefaultLayout::identifier () const
+{
+    static const UString s_id = "default-layout";
+    return s_id;
+}
+
+const UString&
+DBGPerspectiveDefaultLayout::name () const
+{
+    static const UString s_name = _("Default Layout");
+    return s_name;
+}
+
+const UString&
+DBGPerspectiveDefaultLayout::description () const
+{
+    static const UString s_description = _("Nemiver's default layout");
+    return s_description;
+}
+
+void
+DBGPerspectiveDefaultLayout::activate_view (int a_view)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->statuses_notebook);
+
+    m_priv->statuses_notebook->set_current_page (a_view);
+}
+
+void
+DBGPerspectiveDefaultLayout::save_configuration ()
+{
+    THROW_IF_FAIL (m_priv && m_priv->body_main_paned);
+
+    // save the location of the status pane so
+    // that it'll open in the same place
+    // next time.
+    IConfMgr &conf_mgr = m_priv->dbg_perspective.get_conf_mgr ();
+    int pane_location = m_priv->body_main_paned->get_position ();
+
+    NEMIVER_TRY
+    conf_mgr.set_key_value (CONF_KEY_DEFAULT_LAYOUT_STATUS_PANE_LOCATION,
+                            pane_location);
+    NEMIVER_CATCH
+}
+
+void
+DBGPerspectiveDefaultLayout::add_view (Gtk::Widget &a_widget,
+                                       const UString &a_title,
+                                       int a_index)
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->statuses_notebook);
+
+    if (m_priv->views.count (a_index) || a_widget.get_parent ()) {
+        return;
+    }
+
+    m_priv->views.insert (std::make_pair<int, Gtk::Widget&> (a_index, a_widget));
+    a_widget.show_all ();
+    int page_num = m_priv->statuses_notebook->insert_page (a_widget,
+                                                           a_title,
+                                                           a_index);
+    m_priv->statuses_notebook->set_current_page (page_num);
+}
+
+void
+DBGPerspectiveDefaultLayout::remove_view (int a_index)
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->statuses_notebook);
+
+    if (!m_priv->views.count (a_index)) {
+        return;
+    }
+
+    m_priv->statuses_notebook->remove_page (m_priv->views.at (a_index));
+    m_priv->views.erase (a_index);
+}
+
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective-default-layout.h b/src/persp/dbgperspective/nmv-dbg-perspective-default-layout.h
new file mode 100644
index 0000000..d8e4b09
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-dbg-perspective-default-layout.h
@@ -0,0 +1,71 @@
+//Author: Fabien Parent
+/*
+ *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 __NMV_DBG_PERSPECTIVE_DEFAULT_LAYOUT_H__
+#define __NMV_DBG_PERSPECTIVE_DEFAULT_LAYOUT_H__
+
+#include <gtkmm/widget.h>
+#include "common/nmv-safe-ptr-utils.h"
+#include "uicommon/nmv-layout.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+class NEMIVER_API DBGPerspectiveDefaultLayout : public Layout {
+    //non copyable
+    DBGPerspectiveDefaultLayout (const Layout&);
+    DBGPerspectiveDefaultLayout& operator= (const Layout&);
+
+    struct Priv;
+    SafePtr<Priv> m_priv;
+
+public:
+    DBGPerspectiveDefaultLayout ();
+
+    void activate_view (int);
+
+    Gtk::Widget* widget () const;
+
+    void do_init ();
+
+    void do_lay_out (IPerspective&);
+
+    void do_cleanup_layout ();
+
+    const UString& identifier () const;
+
+    const UString& name () const;
+
+    const UString& description () const;
+
+    void save_configuration ();
+
+    void add_view (Gtk::Widget&, const UString&, int);
+
+    void remove_view (int);
+
+    virtual ~DBGPerspectiveDefaultLayout ();
+};//end class DBGPerspectiveDefaultLayout
+
+NEMIVER_END_NAMESPACE (nemiver)
+#endif //__NMV_DBG_PERSPECTIVE_DEFAULT_LAYOUT_H__
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective-dynamic-layout.cc b/src/persp/dbgperspective/nmv-dbg-perspective-dynamic-layout.cc
new file mode 100644
index 0000000..70a823a
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-dbg-perspective-dynamic-layout.cc
@@ -0,0 +1,297 @@
+//Author: Fabien Parent
+/*
+ *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 "config.h"
+#include "common/nmv-safe-ptr.h"
+#include "common/nmv-safe-ptr-utils.h"
+#include "nmv-dbg-perspective.h"
+#include "nmv-dbg-perspective-dynamic-layout.h"
+#include "nmv-ui-utils.h"
+#include "nmv-conf-keys.h"
+
+#include <gdlmm.h>
+#include <gtkmm.h>
+#include <glib/gi18n.h>
+
+using namespace std;
+using namespace nemiver::ui_utils;
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+struct GObjectMMRef {
+
+    void operator () (Glib::Object *a_obj)
+    {
+        if (a_obj) {
+            a_obj->reference ();
+        }
+    }
+};//end GlibObjectRef
+
+struct GObjectMMUnref {
+    void operator () (Glib::Object *a_obj)
+    {
+        if (a_obj) {
+            a_obj->unreference ();
+        }
+    }
+};//end GlibObjectRef
+
+typedef SafePtr<Gdl::DockItem, GObjectMMRef, GObjectMMUnref> DockItemPtr;
+
+/// \brief Dynamic Layout
+///
+/// This layout is based on the external library gdlmm.
+/// The user can directly change the layout, but by default every debugging
+/// panels are inside a single notebook below the sourceview notebook.
+struct DBGPerspectiveDynamicLayout::Priv {
+    SafePtr<Gtk::Box> main_box;
+
+    SafePtr<Gdl::Dock> dock;
+    SafePtr<Gdl::DockBar> dock_bar;
+    Glib::RefPtr<Gdl::DockLayout> dock_layout;
+    SafePtr<Gdl::DockItem> source_item;
+
+    map<int, DockItemPtr> views;
+
+    IDBGPerspective &dbg_perspective;
+
+    Priv (IDBGPerspective &a_dbg_perspective) :
+        dbg_perspective (a_dbg_perspective)
+    {
+    }
+
+    void
+    iconify_item_if_detached (Gdl::DockItem& a_item)
+    {
+        THROW_IF_FAIL (dock);
+
+        if (!a_item.get_parent_object ()) {
+            dock->add_item (a_item, Gdl::DOCK_NONE);
+            a_item.iconify_item ();
+        }
+    }
+
+    const UString&
+    dynamic_layout_configuration_filepath () const
+    {
+        static UString file = Glib::build_filename (Glib::get_home_dir (),
+                                                    ".nemiver",
+                                                    "config",
+                                                    "dynamic-layout.xml");
+        return file;
+    }
+}; //end struct DBGPerspectiveDynamicLayout::Priv
+
+Gtk::Widget*
+DBGPerspectiveDynamicLayout::widget () const
+{
+    return m_priv->main_box.get ();
+}
+
+DBGPerspectiveDynamicLayout::DBGPerspectiveDynamicLayout ()
+{
+    Gdl::init ();
+}
+
+DBGPerspectiveDynamicLayout::~DBGPerspectiveDynamicLayout ()
+{
+    LOG_D ("deleted", "destructor-domain");
+}
+
+void
+DBGPerspectiveDynamicLayout::do_lay_out (IPerspective &a_perspective)
+{
+    m_priv.reset (new Priv (dynamic_cast<IDBGPerspective&> (a_perspective)));
+    THROW_IF_FAIL (m_priv);
+
+    m_priv->source_item.reset
+            (new Gdl::DockItem ("source",
+                                _("Source Code"),
+                                Gdl::DOCK_ITEM_BEH_CANT_CLOSE |
+                                Gdl::DOCK_ITEM_BEH_LOCKED |
+                                Gdl::DOCK_ITEM_BEH_CANT_ICONIFY |
+                                Gdl::DOCK_ITEM_BEH_NO_GRIP));
+    m_priv->source_item->add
+        (m_priv->dbg_perspective.get_source_view_widget ());
+
+    m_priv->dock.reset (new Gdl::Dock);
+    Glib::RefPtr<Gdl::DockMaster> master = m_priv->dock->get_master ();
+    if (master) {
+        master->property_switcher_style () = Gdl::SWITCHER_STYLE_TABS;
+    }
+
+    m_priv->dock->add_item (*m_priv->source_item, Gdl::DOCK_TOP);
+
+    m_priv->dock_bar.reset (new Gdl::DockBar (*m_priv->dock));
+    m_priv->dock_bar->set_style (Gdl::DOCK_BAR_TEXT);
+
+    m_priv->main_box.reset (new Gtk::HBox);
+    m_priv->main_box->pack_start (*m_priv->dock_bar, false, false);
+    m_priv->main_box->pack_end (*m_priv->dock);
+    m_priv->main_box->show_all ();
+
+    m_priv->dock_layout = Gdl::DockLayout::create (*m_priv->dock);
+}
+
+void
+DBGPerspectiveDynamicLayout::do_init ()
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->dock_layout);
+
+    if (Glib::file_test (m_priv->dynamic_layout_configuration_filepath (),
+                         Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) {
+        m_priv->dock_layout->load_from_file
+            (m_priv->dynamic_layout_configuration_filepath ());
+        m_priv->dock_layout->load_layout (identifier ());
+    }
+
+    for (std::map<int, DockItemPtr>::iterator item = m_priv->views.begin ();
+         item != m_priv->views.end ();
+         ++item) {
+        m_priv->iconify_item_if_detached (*item->second);
+    }
+}
+
+void
+DBGPerspectiveDynamicLayout::do_cleanup_layout ()
+{
+    m_priv.reset ();
+}
+
+const UString&
+DBGPerspectiveDynamicLayout::identifier () const
+{
+    static const UString s_id = "dynamic-layout";
+    return s_id;
+}
+
+const UString&
+DBGPerspectiveDynamicLayout::name () const
+{
+    static const UString s_name = _("Dynamic Layout");
+    return s_name;
+}
+
+const UString&
+DBGPerspectiveDynamicLayout::description () const
+{
+    static const UString s_description = _("A layout which can be modified");
+    return s_description;
+}
+
+void
+DBGPerspectiveDynamicLayout::activate_view (int a_view)
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->views.count (a_view));
+
+    DockItemPtr dock_item = m_priv->views[a_view];
+    if (!dock_item) {
+        LOG_ERROR ("Trying to activate a widget with a null pointer");
+        return;
+    }
+
+    if (!dock_item->get_parent_object ()) {
+        dock_item->show_item ();
+    } else {
+        dock_item->present (*dock_item->get_parent_object ());
+    }
+}
+
+void
+DBGPerspectiveDynamicLayout::save_configuration ()
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->dock_layout);
+
+    if (m_priv->dock_layout->is_dirty ()) {
+        m_priv->dock_layout->save_layout (identifier ());
+        m_priv->dock_layout->save_to_file
+            (m_priv->dynamic_layout_configuration_filepath ());
+    }
+}
+
+void
+DBGPerspectiveDynamicLayout::add_view (Gtk::Widget &a_widget,
+                                       const UString &a_title,
+                                       int a_index)
+{
+    THROW_IF_FAIL (m_priv);
+    if (m_priv->views.count (a_index) || a_widget.get_parent ()) {
+        return;
+    }
+
+    // Otherwise the widget takes all the horizontal|vertical place
+    // and cannot be reduced.
+#ifdef WITH_MEMORYVIEW
+    if (a_index == TARGET_TERMINAL_VIEW_INDEX || a_index == MEMORY_VIEW_INDEX) {
+#else
+    if (a_index == TARGET_TERMINAL_VIEW_INDEX) {
+#endif // WITH_MEMORYVIEW
+        IConfMgr &conf_mgr = m_priv->dbg_perspective.get_conf_mgr ();
+        int width = 100;
+        int height = 70;
+
+        NEMIVER_TRY
+        conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_WIDTH, width);
+        conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_HEIGHT, height);
+        NEMIVER_CATCH
+
+        a_widget.set_size_request (width, height);
+    }
+
+    DockItemPtr item (Gtk::manage (new Gdl::DockItem
+            (a_title, a_title, Gdl::DOCK_ITEM_BEH_CANT_CLOSE)));
+    THROW_IF_FAIL (item);
+    item->reference ();
+    m_priv->dock->add_item (*item, Gdl::DOCK_BOTTOM);
+
+    // Attach those widgets to the terminal_item.
+    // Gdl::DOCK_CENTER means that the widget will form a notebook with the
+    // widget they are docked to.
+    if (m_priv->views.size ()) {
+        item->dock_to (*m_priv->views.begin ()->second, Gdl::DOCK_CENTER);
+    }
+
+    m_priv->views[a_index] = item;
+    item->add (a_widget);
+    item->show_all ();
+}
+
+void
+DBGPerspectiveDynamicLayout::remove_view (int a_index)
+{
+    THROW_IF_FAIL (m_priv);
+    if (!m_priv->views.count (a_index)) {
+        return;
+    }
+
+    m_priv->dock->remove (*m_priv->views[a_index]);
+    m_priv->views.erase (a_index);
+}
+
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective-dynamic-layout.h b/src/persp/dbgperspective/nmv-dbg-perspective-dynamic-layout.h
new file mode 100644
index 0000000..489ec2d
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-dbg-perspective-dynamic-layout.h
@@ -0,0 +1,71 @@
+//Author: Fabien Parent
+/*
+ *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 __NMV_DBG_PERSPECTIVE_DYNAMIC_LAYOUT_H__
+#define __NMV_DBG_PERSPECTIVE_DYNAMIC_LAYOUT_H__
+
+#include <gtkmm/widget.h>
+#include "common/nmv-safe-ptr-utils.h"
+#include "uicommon/nmv-layout.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+class NEMIVER_API DBGPerspectiveDynamicLayout : public Layout {
+    //non copyable
+    DBGPerspectiveDynamicLayout (const Layout&);
+    DBGPerspectiveDynamicLayout& operator= (const Layout&);
+
+    struct Priv;
+    SafePtr<Priv> m_priv;
+
+public:
+    DBGPerspectiveDynamicLayout ();
+
+    void activate_view (int);
+
+    Gtk::Widget* widget () const;
+
+    void do_lay_out (IPerspective&);
+
+    void do_init ();
+
+    void do_cleanup_layout ();
+
+    const UString& identifier () const;
+
+    const UString& name () const;
+
+    const UString& description () const;
+
+    void save_configuration ();
+
+    void add_view (Gtk::Widget&, const UString&, int);
+
+    void remove_view (int);
+
+    virtual ~DBGPerspectiveDynamicLayout ();
+};//end class DBGPerspectiveDynamicLayout
+
+NEMIVER_END_NAMESPACE (nemiver)
+#endif //__NMV_DBG_PERSPECTIVE_DYNAMIC_LAYOUT_H__
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective-two-pane-layout.cc b/src/persp/dbgperspective/nmv-dbg-perspective-two-pane-layout.cc
new file mode 100644
index 0000000..f6bda48
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-dbg-perspective-two-pane-layout.cc
@@ -0,0 +1,253 @@
+//Author: Fabien Parent
+/*
+ *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 "config.h"
+#include "common/nmv-safe-ptr.h"
+#include "nmv-dbg-perspective.h"
+#include "nmv-dbg-perspective-two-pane-layout.h"
+#include "nmv-ui-utils.h"
+#include "nmv-conf-keys.h"
+
+#include <gtkmm/notebook.h>
+#include <glib/gi18n.h>
+
+using namespace std;
+using namespace nemiver::ui_utils;
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+/// \brief Two-Pane Layout
+///
+/// This layout is composed of 2 statuses notebook, the first one on the right
+/// of the sourceview notebook, and the second one is below the sourceview
+/// notebook.
+///
+/// The composition of these two notebook is the following:
+/// Right notebook (called vertical pane in the code): memory, register,
+/// and target terminal status view.
+/// Bottom notebook (called horizontal pane in the code): context,
+/// and breakpoints status view.
+struct DBGPerspectiveTwoPaneLayout::Priv {
+    SafePtr<Gtk::Paned> vertical_paned;
+    SafePtr<Gtk::Paned> horizontal_paned;
+    SafePtr<Gtk::Notebook> horizontal_statuses_notebook;
+    SafePtr<Gtk::Notebook> vertical_statuses_notebook;
+    map<int, Gtk::Widget&> views;
+    IDBGPerspective &dbg_perspective;
+
+    Priv (IDBGPerspective &a_dbg_perspective) :
+        dbg_perspective (a_dbg_perspective)
+    {
+    }
+
+    Gtk::Notebook&
+    statuses_notebook (int a_view)
+    {
+        THROW_IF_FAIL (vertical_statuses_notebook);
+        THROW_IF_FAIL (horizontal_statuses_notebook);
+
+        switch ((ViewsIndex) a_view) {
+            case TARGET_TERMINAL_VIEW_INDEX:
+            case REGISTERS_VIEW_INDEX:
+#ifdef WITH_MEMORYVIEW
+            case MEMORY_VIEW_INDEX:
+#endif // WITH_MEMORYVIEW
+                return *vertical_statuses_notebook;
+
+            default:
+                return *horizontal_statuses_notebook;
+        }
+    }
+}; //end struct DBGPerspectiveDefaultLayout::Priv
+
+Gtk::Widget*
+DBGPerspectiveTwoPaneLayout::widget () const
+{
+    return m_priv->vertical_paned.get ();
+}
+
+DBGPerspectiveTwoPaneLayout::DBGPerspectiveTwoPaneLayout ()
+{
+}
+
+DBGPerspectiveTwoPaneLayout::~DBGPerspectiveTwoPaneLayout ()
+{
+    LOG_D ("deleted", "destructor-domain");
+}
+
+void
+DBGPerspectiveTwoPaneLayout::do_lay_out (IPerspective &a_perspective)
+{
+    m_priv.reset (new Priv (dynamic_cast<IDBGPerspective&> (a_perspective)));
+    THROW_IF_FAIL (m_priv);
+
+    m_priv->vertical_paned.reset (new Gtk::VPaned);
+    m_priv->horizontal_paned.reset (new Gtk::HPaned);
+    m_priv->vertical_paned->set_position (350);
+    m_priv->horizontal_paned->set_position (350);
+
+    // set the position of the status pane to the last saved position
+    IConfMgr &conf_mgr = m_priv->dbg_perspective.get_conf_mgr ();
+    int vpane_location = -1;
+    int hpane_location = -1;
+    NEMIVER_TRY
+    conf_mgr.get_key_value (CONF_KEY_TWO_PANE_LAYOUT_STATUS_VPANE_LOCATION,
+                            vpane_location);
+    conf_mgr.get_key_value (CONF_KEY_TWO_PANE_LAYOUT_STATUS_HPANE_LOCATION,
+                            hpane_location);
+    NEMIVER_CATCH
+
+    if (vpane_location >= 0) {
+        m_priv->vertical_paned->set_position (vpane_location);
+    }
+
+    if (hpane_location >= 0) {
+        m_priv->horizontal_paned->set_position (hpane_location);
+    }
+
+    m_priv->horizontal_statuses_notebook.reset (new Gtk::Notebook);
+    m_priv->horizontal_statuses_notebook->set_tab_pos (Gtk::POS_BOTTOM);
+
+    m_priv->vertical_statuses_notebook.reset (new Gtk::Notebook);
+
+    m_priv->vertical_paned->pack1 (*m_priv->horizontal_paned);
+    m_priv->vertical_paned->pack2 (*m_priv->horizontal_statuses_notebook);
+
+    m_priv->horizontal_paned->pack1
+        (m_priv->dbg_perspective.get_source_view_widget (), true, true);
+    m_priv->horizontal_paned->pack2 (*m_priv->vertical_statuses_notebook);
+
+    int width=100, height=70;
+
+    NEMIVER_TRY
+    conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_WIDTH, width);
+    conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_HEIGHT, height);
+    NEMIVER_CATCH
+
+    LOG_DD ("setting status widget min size: width: "
+            << width
+            << ", height: "
+            << height);
+    m_priv->horizontal_statuses_notebook->set_size_request (width, height);
+    m_priv->vertical_statuses_notebook->set_size_request (height, width);
+    m_priv->vertical_paned->show_all ();
+}
+
+void
+DBGPerspectiveTwoPaneLayout::do_init ()
+{
+}
+
+void
+DBGPerspectiveTwoPaneLayout::do_cleanup_layout ()
+{
+    m_priv.reset ();
+}
+
+const UString&
+DBGPerspectiveTwoPaneLayout::identifier () const
+{
+    static const UString s_id = "two-pane-layout";
+    return s_id;
+}
+
+const UString&
+DBGPerspectiveTwoPaneLayout::name () const
+{
+    static const UString s_name = _("Two Status Pane");
+    return s_name;
+}
+
+const UString&
+DBGPerspectiveTwoPaneLayout::description () const
+{
+    static const UString s_description = _("A layout with 2 status pane");
+    return s_description;
+}
+
+void
+DBGPerspectiveTwoPaneLayout::activate_view (int a_view)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (!m_priv->views.count (a_view));
+
+    Gtk::Notebook &status_notebook = m_priv->statuses_notebook (a_view);
+    int page_num = status_notebook.page_num (m_priv->views.at (a_view));
+    THROW_IF_FAIL (page_num >= 0);
+    status_notebook.set_current_page (page_num);
+}
+
+void
+DBGPerspectiveTwoPaneLayout::save_configuration ()
+{
+    THROW_IF_FAIL (m_priv && m_priv->vertical_paned && m_priv->horizontal_paned);
+
+    // save the location of the status pane so
+    // that it'll open in the same place
+    // next time.
+    IConfMgr &conf_mgr = m_priv->dbg_perspective.get_conf_mgr ();
+    int vpane_location = m_priv->vertical_paned->get_position ();
+    int hpane_location = m_priv->horizontal_paned->get_position ();
+
+    NEMIVER_TRY
+    conf_mgr.set_key_value (CONF_KEY_TWO_PANE_LAYOUT_STATUS_VPANE_LOCATION,
+                            vpane_location);
+    conf_mgr.set_key_value (CONF_KEY_TWO_PANE_LAYOUT_STATUS_HPANE_LOCATION,
+                            hpane_location);
+    NEMIVER_CATCH
+}
+
+void
+DBGPerspectiveTwoPaneLayout::add_view (Gtk::Widget &a_widget,
+                                       const UString &a_title,
+                                       int a_index)
+{
+    THROW_IF_FAIL (m_priv);
+    if (m_priv->views.count (a_index) || a_widget.get_parent ()) {
+        return;
+    }
+
+    m_priv->views.insert (std::make_pair<int, Gtk::Widget&> (a_index, a_widget));
+    a_widget.show_all ();
+    Gtk::Notebook &statuses_notebook = m_priv->statuses_notebook (a_index);
+    int page_num = statuses_notebook.insert_page (a_widget, a_title, a_index);
+    statuses_notebook.set_current_page (page_num);
+}
+
+void
+DBGPerspectiveTwoPaneLayout::remove_view (int a_index)
+{
+    THROW_IF_FAIL (m_priv);
+    if (!m_priv->views.count (a_index)) {
+        return;
+    }
+
+    m_priv->statuses_notebook (a_index).remove_page (m_priv->views.at (a_index));
+    m_priv->views.erase (a_index);
+}
+
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective-two-pane-layout.h b/src/persp/dbgperspective/nmv-dbg-perspective-two-pane-layout.h
new file mode 100644
index 0000000..0728ed2
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-dbg-perspective-two-pane-layout.h
@@ -0,0 +1,71 @@
+//Author: Fabien Parent
+/*
+ *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 __NMV_DBG_PERSPECTIVE_TWO_PANE_LAYOUT_H__
+#define __NMV_DBG_PERSPECTIVE_TWO_PANE_LAYOUT_H__
+
+#include <gtkmm/widget.h>
+#include "common/nmv-safe-ptr-utils.h"
+#include "uicommon/nmv-layout.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+class NEMIVER_API DBGPerspectiveTwoPaneLayout : public Layout {
+    //non copyable
+    DBGPerspectiveTwoPaneLayout (const Layout&);
+    DBGPerspectiveTwoPaneLayout& operator= (const Layout&);
+
+    struct Priv;
+    SafePtr<Priv> m_priv;
+
+public:
+    DBGPerspectiveTwoPaneLayout ();
+
+    void activate_view (int);
+
+    Gtk::Widget* widget () const;
+
+    void do_lay_out (IPerspective&);
+
+    void do_init ();
+
+    void do_cleanup_layout ();
+
+    const UString& identifier () const;
+
+    const UString& name () const;
+
+    const UString& description () const;
+
+    void save_configuration ();
+
+    void add_view (Gtk::Widget&, const UString&, int);
+
+    void remove_view (int);
+
+    virtual ~DBGPerspectiveTwoPaneLayout ();
+};//end class DBGPerspectiveTwoPaneLayout
+
+NEMIVER_END_NAMESPACE (nemiver)
+#endif //__NMV_DBG_PERSPECTIVE_TWO_PANE_LAYOUT_H__
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective-wide-layout.cc b/src/persp/dbgperspective/nmv-dbg-perspective-wide-layout.cc
new file mode 100644
index 0000000..cdf4828
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-dbg-perspective-wide-layout.cc
@@ -0,0 +1,208 @@
+//Author: Fabien Parent
+/*
+ *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 "config.h"
+#include "common/nmv-safe-ptr.h"
+#include "nmv-dbg-perspective.h"
+#include "nmv-dbg-perspective-wide-layout.h"
+#include "nmv-ui-utils.h"
+#include "nmv-conf-keys.h"
+
+#include <gtkmm/notebook.h>
+#include <glib/gi18n.h>
+
+using namespace std;
+using namespace nemiver::ui_utils;
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+/// \brief Wide Layout
+///
+/// Every debugging panels are inside a single notebook which is displayed
+/// on the right of the sourceview notebook.
+struct DBGPerspectiveWideLayout::Priv {
+    SafePtr<Gtk::Paned> body_main_paned;
+    SafePtr<Gtk::Notebook> statuses_notebook;
+    map<int, Gtk::Widget&> views;
+    IDBGPerspective &dbg_perspective;
+
+    Priv (IDBGPerspective &a_dbg_perspective) :
+        dbg_perspective (a_dbg_perspective)
+    {
+    }
+}; //end struct DBGPerspectiveWideLayout::Priv
+
+Gtk::Widget*
+DBGPerspectiveWideLayout::widget () const
+{
+    return m_priv->body_main_paned.get ();
+}
+
+DBGPerspectiveWideLayout::DBGPerspectiveWideLayout ()
+{
+}
+
+DBGPerspectiveWideLayout::~DBGPerspectiveWideLayout ()
+{
+    LOG_D ("deleted", "destructor-domain");
+}
+
+void
+DBGPerspectiveWideLayout::do_lay_out (IPerspective &a_perspective)
+{
+    m_priv.reset (new Priv (dynamic_cast<IDBGPerspective&> (a_perspective)));
+    THROW_IF_FAIL (m_priv);
+
+    m_priv->body_main_paned.reset (new Gtk::HPaned);
+
+    // set the position of the status pane to the last saved position
+    IConfMgr &conf_mgr = m_priv->dbg_perspective.get_conf_mgr ();
+    int pane_location = -1; // don't specifically set a location
+                            // if we can't read the last location from gconf
+    NEMIVER_TRY
+    conf_mgr.get_key_value (CONF_KEY_WIDE_LAYOUT_STATUS_PANE_LOCATION,
+                            pane_location);
+    NEMIVER_CATCH
+
+    if (pane_location >= 0) {
+        m_priv->body_main_paned->set_position (pane_location);
+    }
+
+    m_priv->statuses_notebook.reset (new Gtk::Notebook);
+
+    m_priv->body_main_paned->pack2 (*m_priv->statuses_notebook);
+    m_priv->body_main_paned->pack1
+        (m_priv->dbg_perspective.get_source_view_widget (), true, true);
+
+    int width=100, height=70;
+
+    NEMIVER_TRY
+    conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_WIDTH, width);
+    conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_HEIGHT, height);
+    NEMIVER_CATCH
+
+    LOG_DD ("setting status widget min size: width: "
+            << width
+            << ", height: "
+            << height);
+    m_priv->statuses_notebook->set_size_request (width, height);
+    m_priv->body_main_paned->show_all ();
+}
+
+void
+DBGPerspectiveWideLayout::do_init ()
+{
+}
+
+void
+DBGPerspectiveWideLayout::do_cleanup_layout ()
+{
+    m_priv.reset ();
+}
+
+const UString&
+DBGPerspectiveWideLayout::identifier () const
+{
+    static const UString s_id = "wide-layout";
+    return s_id;
+}
+
+const UString&
+DBGPerspectiveWideLayout::name () const
+{
+    static const UString s_name = _("Wide Layout");
+    return s_name;
+}
+
+const UString&
+DBGPerspectiveWideLayout::description () const
+{
+    static const UString s_description = _("A layout for very large monitors");
+    return s_description;
+}
+
+void
+DBGPerspectiveWideLayout::activate_view (int a_view)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->statuses_notebook);
+
+    m_priv->statuses_notebook->set_current_page (a_view);
+}
+
+void
+DBGPerspectiveWideLayout::save_configuration ()
+{
+    THROW_IF_FAIL (m_priv && m_priv->body_main_paned);
+
+    // save the location of the status pane so
+    // that it'll open in the same place
+    // next time.
+    IConfMgr &conf_mgr = m_priv->dbg_perspective.get_conf_mgr ();
+    int pane_location = m_priv->body_main_paned->get_position ();
+
+    NEMIVER_TRY
+    conf_mgr.set_key_value (CONF_KEY_WIDE_LAYOUT_STATUS_PANE_LOCATION,
+                            pane_location);
+    NEMIVER_CATCH
+}
+
+void
+DBGPerspectiveWideLayout::add_view (Gtk::Widget &a_widget,
+                                       const UString &a_title,
+                                       int a_index)
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->statuses_notebook);
+
+    if (m_priv->views.count (a_index) || a_widget.get_parent ()) {
+        return;
+    }
+
+    m_priv->views.insert (std::make_pair<int, Gtk::Widget&> (a_index, a_widget));
+    a_widget.show_all ();
+    int page_num = m_priv->statuses_notebook->insert_page (a_widget,
+                                                           a_title,
+                                                           a_index);
+    m_priv->statuses_notebook->set_current_page (page_num);
+}
+
+void
+DBGPerspectiveWideLayout::remove_view (int a_index)
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->statuses_notebook);
+
+    if (!m_priv->views.count (a_index)) {
+        return;
+    }
+
+    m_priv->statuses_notebook->remove_page (m_priv->views.at (a_index));
+    m_priv->views.erase (a_index);
+}
+
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective-wide-layout.h b/src/persp/dbgperspective/nmv-dbg-perspective-wide-layout.h
new file mode 100644
index 0000000..c57a73c
--- /dev/null
+++ b/src/persp/dbgperspective/nmv-dbg-perspective-wide-layout.h
@@ -0,0 +1,71 @@
+//Author: Fabien Parent
+/*
+ *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 __NMV_DBG_PERSPECTIVE_WIDE_LAYOUT_H__
+#define __NMV_DBG_PERSPECTIVE_WIDE_LAYOUT_H__
+
+#include <gtkmm/widget.h>
+#include "common/nmv-safe-ptr-utils.h"
+#include "uicommon/nmv-layout.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+class NEMIVER_API DBGPerspectiveWideLayout : public Layout {
+    //non copyable
+    DBGPerspectiveWideLayout (const Layout&);
+    DBGPerspectiveWideLayout& operator= (const Layout&);
+
+    struct Priv;
+    SafePtr<Priv> m_priv;
+
+public:
+    DBGPerspectiveWideLayout ();
+
+    void activate_view (int);
+
+    Gtk::Widget* widget () const;
+
+    void do_lay_out (IPerspective&);
+
+    void do_init ();
+
+    void do_cleanup_layout ();
+
+    const UString& identifier () const;
+
+    const UString& name () const;
+
+    const UString& description () const;
+
+    void save_configuration ();
+
+    void add_view (Gtk::Widget&, const UString&, int);
+
+    void remove_view (int);
+
+    virtual ~DBGPerspectiveWideLayout ();
+};//end class DBGPerspectiveDefaultLayout
+
+NEMIVER_END_NAMESPACE (nemiver)
+#endif //__NMV_DBG_PERSPECTIVE_WIDE_LAYOUT_H__
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index 8b56992..fde47b5 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -90,6 +90,13 @@
 #include "nmv-watchpoint-dialog.h"
 #include "nmv-debugger-utils.h"
 #include "nmv-set-jump-to-dialog.h"
+#include "nmv-dbg-perspective-default-layout.h"
+#include "nmv-dbg-perspective-wide-layout.h"
+#include "nmv-dbg-perspective-two-pane-layout.h"
+#ifdef WITH_DYNAMICLAYOUT
+#include "nmv-dbg-perspective-dynamic-layout.h"
+#endif // WITH_DYNAMICLAYOUT
+#include "nmv-layout-manager.h"
 
 using namespace std;
 using namespace nemiver::common;
@@ -107,11 +114,11 @@ const char *STEP_OVER         = "nmv-step-over";
 const char *STEP_OUT          = "nmv-step-out";
 
 // labels for widget tabs in the status notebook
-const char *CONTEXT_TITLE           = _("Context");
-const char *TARGET_TERMINAL_TITLE   = _("Target Terminal");
-const char *BREAKPOINTS_TITLE       = _("Breakpoints");
-const char *REGISTERS_VIEW_TITLE    = _("Registers");
-const char *MEMORY_VIEW_TITLE       = _("Memory");
+const char *CONTEXT_VIEW_TITLE         = _("Context");
+const char *TARGET_TERMINAL_VIEW_TITLE = _("Target Terminal");
+const char *BREAKPOINTS_VIEW_TITLE     = _("Breakpoints");
+const char *REGISTERS_VIEW_TITLE       = _("Registers");
+const char *MEMORY_VIEW_TITLE          = _("Memory");
 
 const char *SESSION_NAME = "sessionname";
 const char *PROGRAM_NAME = "programname";
@@ -127,7 +134,7 @@ const char *DISASSEMBLY_TITLE = "<Disassembly>";
 
 static const int NUM_INSTR_TO_DISASSEMBLE = 20;
 
-
+const char *DBG_PERSPECTIVE_DEFAULT_LAYOUT = "default-layout";
 
 const Gtk::StockID STOCK_SET_BREAKPOINT (SET_BREAKPOINT);
 const Gtk::StockID STOCK_LINE_POINTER (LINE_POINTER);
@@ -404,6 +411,7 @@ private:
     bool on_file_content_changed (const UString &a_path);
     void on_notebook_tabs_reordered(Gtk::Widget* a_page, guint a_page_num);
 
+    void on_layout_changed ();
     void on_activate_context_view ();
     void on_activate_target_terminal_view ();
     void on_activate_breakpoints_view ();
@@ -423,8 +431,8 @@ private:
                          const UString &icon_dir,
                          const UString &icon_name);
     void add_perspective_menu_entries ();
-    void init_perspective_menu_entries ();
     void add_perspective_toolbar_entries ();
+    void register_layouts ();
     void init_icon_factory ();
     void init_actions ();
     void init_toolbar ();
@@ -469,6 +477,7 @@ private:
     PopupTip& get_popup_tip ();
     void hide_popup_tip_if_mouse_is_outside (int x, int y);
     FindTextDialog& get_find_text_dialog ();
+    void add_views_to_layout ();
 
 public:
 
@@ -484,6 +493,8 @@ public:
 
     Gtk::Widget* get_body ();
 
+    Gtk::Widget& get_source_view_widget ();
+
     IWorkbench& get_workbench ();
 
     void edit_workbench_menu ();
@@ -748,18 +759,6 @@ public:
 
     ThreadList& get_thread_list ();
 
-    void set_show_context_view (bool);
-
-    void set_show_terminal_view (bool);
-
-    void set_show_breakpoints_view (bool);
-
-    void set_show_registers_view (bool);
-
-#ifdef WITH_MEMORYVIEW
-    void set_show_memory_view (bool);
-#endif // WITH_MEMORYVIEW
-
     bool set_where (const IDebugger::Frame &a_frame,
                     bool a_do_scroll = true,
                     bool a_try_hard = false);
@@ -795,13 +794,12 @@ public:
 
     bool do_unmonitor_file (const UString &a_path);
 
-    void activate_status_view(Gtk::Widget& page);
-
     bool agree_to_shutdown ();
 
     sigc::signal<void, bool>& activated_signal ();
     sigc::signal<void, bool>& attached_to_target_signal ();
     sigc::signal<void, bool>& debugger_ready_signal ();
+    sigc::signal<void>& layout_changed_signal ();
     sigc::signal<void>& debugger_not_started_signal ();
     sigc::signal<void>& going_to_run_target_signal ();
     sigc::signal<void>& default_config_read_signal ();
@@ -861,8 +859,6 @@ struct DBGPerspective::Priv {
     list<UString> session_search_paths;
     list<UString> global_search_paths;
     map<UString, bool> paths_to_ignore;
-    Glib::RefPtr<Gtk::Builder> body_builder;
-    SafePtr<Gtk::Window> body_window;
     SafePtr<CallStack> call_stack;
     SafePtr<Gtk::ScrolledWindow> call_stack_scrolled_win;
     SafePtr<Gtk::ScrolledWindow> thread_list_scrolled_win;
@@ -881,10 +877,11 @@ struct DBGPerspective::Priv {
     Gtk::UIManager::ui_merge_id toolbar_merge_id;
     Gtk::UIManager::ui_merge_id contextual_menu_merge_id;
     Gtk::Widget *contextual_menu;
-    Gtk::Box *top_box;
-    SafePtr<Gtk::Paned> body_main_paned;
+
+    LayoutManager layout_mgr;
     IWorkbench *workbench;
     SafePtr<Gtk::HBox> toolbar;
+    SafePtr<Gtk::Notebook> sourceviews_notebook;
     SafePtr<SpinnerToolItem> throbber;
     sigc::signal<void, bool> activated_signal;
     sigc::signal<void, bool> attached_to_target_signal;
@@ -892,21 +889,12 @@ struct DBGPerspective::Priv {
     sigc::signal<void> debugger_not_started_signal;
     sigc::signal<void> going_to_run_target_signal;
     sigc::signal<void> default_config_read_signal;
-    bool context_paned_view_is_visible;
-    bool terminal_view_is_visible;
-    bool breakpoints_view_is_visible;
-    bool registers_view_is_visible;
-#ifdef WITH_MEMORYVIEW
-    bool memory_view_is_visible;
-#endif // WITH_MEMORYVIEW
-    Gtk::Notebook *sourceviews_notebook;
     map<UString, int> path_2_pagenum_map;
     map<UString, int> basename_2_pagenum_map;
     map<int, SourceEditor*> pagenum_2_source_editor_map;
     map<int, UString> pagenum_2_path_map;
     typedef map<UString, Glib::RefPtr<Gio::FileMonitor> > Path2MonitorMap;
     Path2MonitorMap path_2_monitor_map;
-    Gtk::Notebook *statuses_notebook;
     SafePtr<LocalVarsInspector> variables_editor;
     SafePtr<Gtk::ScrolledWindow> variables_editor_scrolled_win;
     SafePtr<Terminal> terminal;
@@ -977,18 +965,7 @@ struct DBGPerspective::Priv {
         toolbar_merge_id (0),
         contextual_menu_merge_id(0),
         contextual_menu (0),
-        top_box (0),
-        /*body_main_paned (0),*/
         workbench (0),
-        context_paned_view_is_visible (false),
-        terminal_view_is_visible (false),
-        breakpoints_view_is_visible (false),
-        registers_view_is_visible (false),
-#ifdef WITH_MEMORYVIEW
-        memory_view_is_visible (false),
-#endif // WITH_MEMORYVIEW
-        sourceviews_notebook (0),
-        statuses_notebook (0),
         current_page_num (0),
         show_dbg_errors (false),
         use_system_font (true),
@@ -1007,6 +984,13 @@ struct DBGPerspective::Priv {
     {
     }
 
+    Layout&
+    layout ()
+    {
+        Layout *layout = layout_mgr.layout ();
+        THROW_IF_FAIL (layout);
+        return *layout;
+    }
 
     void
     modify_source_editor_style (Glib::RefPtr<Gsv::StyleScheme> a_style_scheme)
@@ -1173,20 +1157,6 @@ struct DBGPerspective::Priv {
 
 };//end struct DBGPerspective::Priv
 
-enum ViewsIndex
-{
-    COMMAND_VIEW_INDEX=0,
-    CONTEXT_VIEW_INDEX,
-    TERMINAL_VIEW_INDEX,
-    BREAKPOINTS_VIEW_INDEX,
-    REGISTERS_VIEW_INDEX,
-#ifdef WITH_MEMORYVIEW
-    MEMORY_VIEW_INDEX,
-#endif // WITH_MEMORYVIEW
-    TARGET_OUTPUT_VIEW_INDEX,
-    ERROR_VIEW_INDEX
-};
-
 #ifndef CHECK_P_INIT
 #define CHECK_P_INIT THROW_IF_FAIL(m_priv && m_priv->initialized);
 #endif
@@ -2147,22 +2117,18 @@ DBGPerspective::update_toggle_menu_text (const IDebugger::Breakpoint *a_bp)
 void
 DBGPerspective::on_shutdown_signal ()
 {
-    LOG_FUNCTION_SCOPE_NORMAL_DD;
-    NEMIVER_TRY
-
-    // save the location of the status pane so
-    // that it'll open in the same place
-    // next time.
     IConfMgr &conf_mgr = get_conf_mgr ();
-    int pane_location = m_priv->body_main_paned->get_position();
     int context_pane_location = get_context_paned ().get_position ();
-
     NEMIVER_TRY
-    conf_mgr.set_key_value (CONF_KEY_STATUS_PANE_LOCATION, pane_location);
     conf_mgr.set_key_value (CONF_KEY_CONTEXT_PANE_LOCATION,
                             context_pane_location);
+
+    m_priv->layout ().save_configuration ();
     NEMIVER_CATCH_NOX
 
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+    NEMIVER_TRY
+
     if (m_priv->prog_path == "") {
         return;
     }
@@ -2550,7 +2516,6 @@ DBGPerspective::on_debugger_running_signal ()
     LOG_FUNCTION_SCOPE_NORMAL_DD;
     NEMIVER_TRY
     THROW_IF_FAIL (m_priv->throbber);
-    THROW_IF_FAIL (m_priv->sourceviews_notebook);
     workbench ().get_root_window ().get_window ()->set_cursor
                                                 (Gdk::Cursor::create (Gdk::WATCH));
     m_priv->throbber->start ();
@@ -2801,22 +2766,15 @@ DBGPerspective::on_notebook_tabs_reordered (Gtk::Widget* /*a_page*/,
 }
 
 void
-DBGPerspective::activate_status_view (Gtk::Widget &a_page)
+DBGPerspective::on_layout_changed ()
 {
-    int pagenum = 0;
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
-    THROW_IF_FAIL (m_priv);
-    THROW_IF_FAIL (m_priv->statuses_notebook);
+    NEMIVER_TRY
 
-    pagenum = m_priv->statuses_notebook->page_num (a_page);
-    if (pagenum != -1) {
-        if (m_priv->statuses_notebook->get_current_page () != pagenum)
-            m_priv->statuses_notebook->set_current_page (pagenum);
-        a_page.grab_focus ();
-    } else {
-        LOG_DD ("Invalid Pagenum");
-    }
+    add_views_to_layout ();
+
+    NEMIVER_CATCH
 }
 
 void
@@ -2825,7 +2783,8 @@ DBGPerspective::on_activate_context_view ()
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
     NEMIVER_TRY
-    activate_status_view (get_context_paned ());
+    THROW_IF_FAIL (m_priv);
+    m_priv->layout ().activate_view (CONTEXT_VIEW_INDEX);
     NEMIVER_CATCH
 }
 
@@ -2836,7 +2795,8 @@ DBGPerspective::on_activate_target_terminal_view ()
 
     NEMIVER_TRY
 
-    activate_status_view (get_terminal_box ());
+    THROW_IF_FAIL (m_priv);
+    m_priv->layout ().activate_view (TARGET_TERMINAL_VIEW_INDEX);
 
     NEMIVER_CATCH
 }
@@ -2848,7 +2808,8 @@ DBGPerspective::on_activate_breakpoints_view ()
 
     NEMIVER_TRY
 
-    activate_status_view (get_breakpoints_scrolled_win ());
+    THROW_IF_FAIL (m_priv);
+    m_priv->layout ().activate_view (BREAKPOINTS_VIEW_INDEX);
 
     NEMIVER_CATCH
 }
@@ -2860,7 +2821,8 @@ DBGPerspective::on_activate_registers_view ()
 
     NEMIVER_TRY
 
-    activate_status_view (get_registers_scrolled_win ());
+    THROW_IF_FAIL (m_priv);
+    m_priv->layout ().activate_view (REGISTERS_VIEW_INDEX);
 
     NEMIVER_CATCH
 }
@@ -2873,7 +2835,8 @@ DBGPerspective::on_activate_memory_view ()
 
     NEMIVER_TRY
 
-    activate_status_view (get_memory_view ().widget ());
+    THROW_IF_FAIL (m_priv);
+    m_priv->layout ().activate_view (MEMORY_VIEW_INDEX);
 
     NEMIVER_CATCH
 }
@@ -2982,19 +2945,6 @@ DBGPerspective::add_perspective_menu_entries ()
 }
 
 void
-DBGPerspective::init_perspective_menu_entries ()
-{
-    set_show_terminal_view (true);
-    set_show_context_view (true);
-    set_show_breakpoints_view (true);
-    set_show_registers_view (true);
-#ifdef WITH_MEMORYVIEW
-    set_show_memory_view (true);
-#endif // WITH_MEMORYVIEW
-    m_priv->statuses_notebook->set_current_page (0);
-}
-
-void
 DBGPerspective::add_perspective_toolbar_entries ()
 {
     string relative_path = Glib::build_filename ("menus",
@@ -3369,7 +3319,7 @@ DBGPerspective::init_actions ()
         {
             "ActivateTargetTerminalViewMenuAction",
             nil_stock_id,
-            TARGET_TERMINAL_TITLE,
+            TARGET_TERMINAL_VIEW_TITLE,
             _("Switch to Target Terminal View"),
             sigc::mem_fun (*this,
                            &DBGPerspective::on_activate_target_terminal_view),
@@ -3380,7 +3330,7 @@ DBGPerspective::init_actions ()
         {
             "ActivateContextViewMenuAction",
             nil_stock_id,
-            CONTEXT_TITLE,
+            CONTEXT_VIEW_TITLE,
             _("Switch to Context View"),
             sigc::mem_fun (*this,
                            &DBGPerspective::on_activate_context_view),
@@ -3391,7 +3341,7 @@ DBGPerspective::init_actions ()
         {
             "ActivateBreakpointsViewMenuAction",
             nil_stock_id,
-            BREAKPOINTS_TITLE,
+            BREAKPOINTS_VIEW_TITLE,
             _("Switch to Breakpoints View"),
             sigc::mem_fun (*this,
                            &DBGPerspective::on_activate_breakpoints_view),
@@ -3668,57 +3618,7 @@ DBGPerspective::init_toolbar ()
 void
 DBGPerspective::init_body ()
 {
-    string relative_path = Glib::build_filename ("ui",
-                                                 "bodycontainer.ui");
-    string absolute_path;
-    THROW_IF_FAIL (build_absolute_resource_path
-                    (Glib::filename_to_utf8 (relative_path), absolute_path));
-    m_priv->body_builder = Gtk::Builder::create_from_file (absolute_path);
-    m_priv->body_window.reset
-        (ui_utils::get_widget_from_gtkbuilder<Gtk::Window> (m_priv->body_builder,
-                                                       "bodycontainer"));
-    m_priv->top_box =
-        ui_utils::get_widget_from_gtkbuilder<Gtk::Box> (m_priv->body_builder,
-                                                   "topbox");
-    m_priv->body_main_paned.reset
-        (ui_utils::get_widget_from_gtkbuilder<Gtk::Paned> (m_priv->body_builder,
-                                                      "mainbodypaned"));
-    // set the position of the status pane to the last saved position
     IConfMgr &conf_mgr = get_conf_mgr ();
-    int pane_location = -1; // don't specifically set a location
-                            // if we can't read the last location from gconf
-    NEMIVER_TRY
-    conf_mgr.get_key_value (CONF_KEY_STATUS_PANE_LOCATION, pane_location);
-    NEMIVER_CATCH_NOX
-
-    if (pane_location > 0) {
-        m_priv->body_main_paned->set_position (pane_location);
-    }
-
-    m_priv->sourceviews_notebook =
-        ui_utils::get_widget_from_gtkbuilder<Gtk::Notebook> (m_priv->body_builder,
-                                                        "sourceviewsnotebook");
-    m_priv->sourceviews_notebook->remove_page ();
-    m_priv->sourceviews_notebook->set_show_tabs ();
-    m_priv->sourceviews_notebook->set_scrollable ();
-    m_priv->sourceviews_notebook->signal_page_reordered ().connect
-        (sigc::mem_fun (this, &DBGPerspective::on_notebook_tabs_reordered));
-
-    m_priv->statuses_notebook =
-        ui_utils::get_widget_from_gtkbuilder<Gtk::Notebook> (m_priv->body_builder,
-                                                        "statusesnotebook");
-    int width=100, height=70;
-
-    NEMIVER_TRY
-    conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_WIDTH, width);
-    conf_mgr.get_key_value (CONF_KEY_STATUS_WIDGET_MINIMUM_HEIGHT, height);
-    NEMIVER_CATCH_NOX
-
-    LOG_DD ("setting status widget min size: width: "
-            << width
-            << ", height: "
-            << height);
-    m_priv->statuses_notebook->set_size_request (width, height);
 
     get_thread_list_scrolled_win ().add (get_thread_list ().widget ());
     get_call_stack_paned ().add1 (get_thread_list_scrolled_win ());
@@ -3728,7 +3628,6 @@ DBGPerspective::init_body ()
     get_context_paned ().pack1 (get_call_stack_paned ());
     get_context_paned ().pack2 (get_local_vars_inspector_scrolled_win ());
 
-
     int context_pane_location = -1;
     NEMIVER_TRY
     conf_mgr.get_key_value (CONF_KEY_CONTEXT_PANE_LOCATION,
@@ -3744,13 +3643,27 @@ DBGPerspective::init_body ()
     get_breakpoints_scrolled_win ().add (get_breakpoints_view ().widget());
     get_registers_scrolled_win ().add (get_registers_view ().widget());
 
-    //unparent the body_main_paned, so that we can pack it
-    //in the workbench later
-    m_priv->top_box->remove (*m_priv->body_main_paned);
-    m_priv->body_main_paned->show_all ();
+    m_priv->sourceviews_notebook.reset (new Gtk::Notebook);
+    m_priv->sourceviews_notebook->remove_page ();
+    m_priv->sourceviews_notebook->set_show_tabs ();
+    m_priv->sourceviews_notebook->set_scrollable ();
+#if GTK_CHECK_VERSION (2, 10, 0)
+    m_priv->sourceviews_notebook->signal_page_reordered ().connect
+        (sigc::mem_fun (this, &DBGPerspective::on_notebook_tabs_reordered));
+#endif
+
+    UString layout = DBG_PERSPECTIVE_DEFAULT_LAYOUT;
+    NEMIVER_TRY
+    conf_mgr.get_key_value (CONF_KEY_DBG_PERSPECTIVE_LAYOUT, layout);
+
+    // If the layout is not registered, we use the default layout
+    if (!m_priv->layout_mgr.is_layout_registered (layout)) {
+        layout = DBG_PERSPECTIVE_DEFAULT_LAYOUT;
+    }
+    NEMIVER_CATCH_NOX
 
-    //must be last
-    init_perspective_menu_entries ();
+    m_priv->layout_mgr.load_layout (layout, *this);
+    add_views_to_layout ();
 }
 
 void
@@ -3783,6 +3696,9 @@ DBGPerspective::init_signals ()
 
     default_config_read_signal ().connect (sigc::mem_fun (this,
                 &DBGPerspective::on_default_config_read));
+
+    m_priv->layout_mgr.layout_changed_signal ().connect (sigc::mem_fun
+            (*this, &DBGPerspective::on_layout_changed));
 }
 
 /// Connect slots (callbacks) to the signals emitted by the
@@ -4262,6 +4178,8 @@ DBGPerspective::bring_source_as_current (SourceEditor *a_editor)
     if (a_editor == 0)
         return;
 
+    THROW_IF_FAIL (m_priv);
+
     UString path = a_editor->get_path ();
     map<UString, int>::iterator iter =
         m_priv->path_2_pagenum_map.find (path);
@@ -4957,6 +4875,33 @@ DBGPerspective::get_find_text_dialog ()
 }
 
 void
+DBGPerspective::add_views_to_layout ()
+{
+    THROW_IF_FAIL (m_priv);
+
+#ifdef WITH_MEMORYVIEW
+    m_priv->layout ().add_view (get_memory_view ().widget (),
+                                MEMORY_VIEW_TITLE,
+                                MEMORY_VIEW_INDEX);
+#endif // WITH_MEMORYVIEW
+    m_priv->layout ().add_view (get_registers_scrolled_win (),
+                                REGISTERS_VIEW_TITLE,
+                                REGISTERS_VIEW_INDEX);
+    m_priv->layout ().add_view (get_breakpoints_scrolled_win (),
+                                BREAKPOINTS_VIEW_TITLE,
+                                BREAKPOINTS_VIEW_INDEX);
+    m_priv->layout ().add_view (get_context_paned (),
+                                CONTEXT_VIEW_TITLE,
+                                CONTEXT_VIEW_INDEX);
+    m_priv->layout ().add_view (get_terminal_box (),
+                                TARGET_TERMINAL_VIEW_TITLE,
+                                TARGET_TERMINAL_VIEW_INDEX);
+
+    m_priv->layout ().do_init ();
+
+}
+
+void
 DBGPerspective::record_and_save_session (ISessMgr::Session &a_session)
 {
     THROW_IF_FAIL (m_priv);
@@ -5087,6 +5032,7 @@ DBGPerspective::do_init (IWorkbench *a_workbench)
 {
     THROW_IF_FAIL (m_priv);
     m_priv->workbench = a_workbench;
+    register_layouts ();
     init_icon_factory ();
     init_actions ();
     init_toolbar ();
@@ -5114,6 +5060,23 @@ DBGPerspective::get_perspective_identifier ()
 }
 
 void
+DBGPerspective::register_layouts ()
+{
+    THROW_IF_FAIL (m_priv);
+
+    m_priv->layout_mgr.register_layout
+        (LayoutSafePtr (new DBGPerspectiveDefaultLayout));
+    m_priv->layout_mgr.register_layout
+        (LayoutSafePtr (new DBGPerspectiveTwoPaneLayout));
+    m_priv->layout_mgr.register_layout
+        (LayoutSafePtr (new DBGPerspectiveWideLayout));
+#ifdef WITH_DYNAMICLAYOUT
+    m_priv->layout_mgr.register_layout
+        (LayoutSafePtr (new DBGPerspectiveDynamicLayout));
+#endif // WITH_DYNAMICLAYOUT
+}
+
+void
 DBGPerspective::get_toolbars (list<Gtk::Widget*>  &a_tbs)
 {
     CHECK_P_INIT;
@@ -5124,7 +5087,13 @@ Gtk::Widget*
 DBGPerspective::get_body ()
 {
     CHECK_P_INIT;
-    return m_priv->body_main_paned.get ();
+    return m_priv->layout ().widget ();
+}
+
+Gtk::Widget&
+DBGPerspective::get_source_view_widget ()
+{
+    return *m_priv->sourceviews_notebook;
 }
 
 IWorkbench&
@@ -5140,7 +5109,6 @@ DBGPerspective::edit_workbench_menu ()
     CHECK_P_INIT;
 
     add_perspective_menu_entries ();
-    //init_perspective_menu_entries ();
 }
 
 SourceEditor*
@@ -5582,6 +5550,8 @@ DBGPerspective::update_file_maps ()
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
 
+    THROW_IF_FAIL (m_priv);
+
     m_priv->path_2_pagenum_map.clear ();
     m_priv->basename_2_pagenum_map.clear ();
     m_priv->pagenum_2_source_editor_map.clear ();
@@ -6278,7 +6248,7 @@ void
 DBGPerspective::edit_preferences ()
 {
     THROW_IF_FAIL (m_priv);
-    PreferencesDialog dialog (workbench (), plugin_path ());
+    PreferencesDialog dialog (*this, m_priv->layout_mgr, plugin_path ());
     dialog.run ();
 }
 
@@ -8076,138 +8046,6 @@ DBGPerspective::get_memory_view ()
 }
 #endif // WITH_MEMORYVIEW
 
-void
-DBGPerspective::set_show_context_view (bool a_show)
-{
-    if (a_show) {
-        if (!get_context_paned ().get_parent ()
-            && m_priv->context_paned_view_is_visible == false) {
-            get_context_paned ().show_all ();
-            int page_num = m_priv->statuses_notebook->insert_page
-                                (get_context_paned (),
-                                 CONTEXT_TITLE,
-                                 CONTEXT_VIEW_INDEX);
-            m_priv->context_paned_view_is_visible = true;
-            m_priv->statuses_notebook->set_current_page (page_num);
-        }
-    } else {
-        if (get_context_paned ().get_parent ()
-            && m_priv->context_paned_view_is_visible) {
-            LOG_DD ("removing context pane");
-            m_priv->statuses_notebook->remove_page
-                                (get_context_paned ());
-            m_priv->context_paned_view_is_visible = false;
-        }
-        m_priv->context_paned_view_is_visible = false;
-    }
-}
-
-void
-DBGPerspective::set_show_terminal_view (bool a_show)
-{
-    if (a_show) {
-        if (!get_terminal_box ().get_parent ()
-            && m_priv->terminal_view_is_visible == false) {
-            get_terminal_box ().show_all ();
-            int page_num = m_priv->statuses_notebook->insert_page
-                                            (get_terminal_box (),
-                                             TARGET_TERMINAL_TITLE,
-                                             TERMINAL_VIEW_INDEX);
-            m_priv->terminal_view_is_visible = true;
-            m_priv->statuses_notebook->set_current_page (page_num);
-        }
-    } else {
-        if (get_terminal_box ().get_parent ()
-            && m_priv->terminal_view_is_visible) {
-            LOG_DD ("removing terminal view");
-            m_priv->statuses_notebook->remove_page
-                                        (get_terminal_box ());
-            m_priv->terminal_view_is_visible = false;
-        }
-        m_priv->terminal_view_is_visible = false;
-    }
-}
-
-void
-DBGPerspective::set_show_breakpoints_view (bool a_show)
-{
-    if (a_show) {
-        if (!get_breakpoints_scrolled_win ().get_parent ()
-            && m_priv->breakpoints_view_is_visible == false) {
-            get_breakpoints_scrolled_win ().show_all ();
-            int page_num = m_priv->statuses_notebook->insert_page
-                                            (get_breakpoints_scrolled_win (),
-                                             BREAKPOINTS_TITLE,
-                                             BREAKPOINTS_VIEW_INDEX);
-            m_priv->breakpoints_view_is_visible = true;
-            m_priv->statuses_notebook->set_current_page (page_num);
-        }
-    } else {
-        if (get_breakpoints_scrolled_win ().get_parent ()
-            && m_priv->breakpoints_view_is_visible) {
-            LOG_DD ("removing breakpoints view");
-            m_priv->statuses_notebook->remove_page
-                                        (get_breakpoints_scrolled_win ());
-            m_priv->breakpoints_view_is_visible = false;
-        }
-        m_priv->breakpoints_view_is_visible = false;
-    }
-}
-
-void
-DBGPerspective::set_show_registers_view (bool a_show)
-{
-    if (a_show) {
-        if (!get_registers_scrolled_win ().get_parent ()
-            && m_priv->registers_view_is_visible == false) {
-            get_registers_scrolled_win ().show_all ();
-            int page_num = m_priv->statuses_notebook->insert_page
-                                            (get_registers_scrolled_win (),
-                                             REGISTERS_VIEW_TITLE,
-                                             REGISTERS_VIEW_INDEX);
-            m_priv->registers_view_is_visible = true;
-            m_priv->statuses_notebook->set_current_page (page_num);
-        }
-    } else {
-        if (get_registers_scrolled_win ().get_parent ()
-            && m_priv->registers_view_is_visible) {
-            LOG_DD ("removing registers view");
-            m_priv->statuses_notebook->remove_page
-                                        (get_registers_scrolled_win ());
-            m_priv->registers_view_is_visible = false;
-        }
-        m_priv->registers_view_is_visible = false;
-    }
-}
-
-#ifdef WITH_MEMORYVIEW
-void
-DBGPerspective::set_show_memory_view (bool a_show)
-{
-    if (a_show) {
-        if (!get_memory_view ().widget ().get_parent ()
-            && m_priv->memory_view_is_visible == false) {
-            get_memory_view ().widget ().show_all ();
-            int page_num = m_priv->statuses_notebook->insert_page
-                                            (get_memory_view ().widget (),
-                                             MEMORY_VIEW_TITLE,
-                                             MEMORY_VIEW_INDEX);
-            m_priv->memory_view_is_visible = true;
-            m_priv->statuses_notebook->set_current_page (page_num);
-        }
-    } else {
-        if (get_memory_view ().widget ().get_parent ()
-            && m_priv->memory_view_is_visible) {
-            LOG_DD ("removing memory view");
-            m_priv->statuses_notebook->remove_page
-                                        (get_memory_view ().widget ());
-            m_priv->memory_view_is_visible = false;
-        }
-        m_priv->memory_view_is_visible = false;
-    }
-}
-#endif // WITH_MEMORYVIEW
-
 
 struct ScrollTextViewToEndClosure {
     Gtk::TextView* text_view;
@@ -8248,6 +8086,13 @@ DBGPerspective::debugger_ready_signal ()
 }
 
 sigc::signal<void>&
+DBGPerspective::layout_changed_signal ()
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->layout_mgr.layout_changed_signal ();
+}
+
+sigc::signal<void>&
 DBGPerspective::debugger_not_started_signal ()
 {
     return m_priv->debugger_not_started_signal;
@@ -8270,7 +8115,7 @@ DBGPerspective::agree_to_shutdown ()
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;
     if (debugger ()->is_attached_to_target ()) {
-	UString message;
+        UString message;
         message.printf (_("There is a program being currently debugged. "
                           "Do you really want to exit from the debugger?"));
         if (nemiver::ui_utils::ask_yes_no_question (message) ==
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.h b/src/persp/dbgperspective/nmv-dbg-perspective.h
index 0a3af43..ddb00ff 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.h
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.h
@@ -29,10 +29,28 @@
 #include "nmv-i-perspective.h"
 #include "nmv-i-debugger.h"
 #include "nmv-sess-mgr.h"
+#include "nmv-i-conf-mgr.h"
 #include <sigc++/trackable.h>
 
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 
+extern const char *CONTEXT_VIEW_TITLE;
+extern const char *TARGET_TERMINAL_VIEW_TITLE;
+extern const char *BREAKPOINTS_VIEW_TITLE;
+extern const char *REGISTERS_VIEW_TITLE;
+extern const char *MEMORY_VIEW_TITLE;
+
+enum ViewsIndex
+{
+    TARGET_TERMINAL_VIEW_INDEX = 0,
+    CONTEXT_VIEW_INDEX,
+    BREAKPOINTS_VIEW_INDEX,
+    REGISTERS_VIEW_INDEX,
+#ifdef WITH_MEMORYVIEW
+    MEMORY_VIEW_INDEX
+#endif // WITH_MEMORYVIEW
+};
+
 class SourceEditor;
 class NEMIVER_API IDBGPerspective : public IPerspective {
     //non copyable
@@ -56,6 +74,8 @@ public:
 
     virtual Gtk::Widget* get_body () = 0;
 
+    virtual Gtk::Widget& get_source_view_widget () = 0;
+
     virtual IWorkbench& get_workbench () = 0;
 
     virtual void edit_workbench_menu () = 0;
@@ -153,6 +173,8 @@ public:
 
     virtual Gtk::Widget* get_contextual_menu () = 0;
 
+    virtual IConfMgr& get_conf_mgr () = 0;
+
     virtual bool uses_launch_terminal () const = 0;
 
     virtual void uses_launch_terminal (bool a_flag) = 0;
@@ -161,6 +183,8 @@ public:
 
     virtual sigc::signal<void, bool>& debugger_ready_signal () = 0;
 
+    virtual sigc::signal<void>& layout_changed_signal () = 0;
+
     virtual bool agree_to_shutdown () = 0;
 };//end class IDBGPerspective
 
diff --git a/src/persp/dbgperspective/nmv-preferences-dialog.cc b/src/persp/dbgperspective/nmv-preferences-dialog.cc
index 6b5383a..a801055 100644
--- a/src/persp/dbgperspective/nmv-preferences-dialog.cc
+++ b/src/persp/dbgperspective/nmv-preferences-dialog.cc
@@ -29,8 +29,9 @@
 #include "nmv-preferences-dialog.h"
 #include "nmv-ui-utils.h"
 #include "nmv-i-conf-mgr.h"
-#include "nmv-i-workbench.h"
+#include "nmv-i-perspective.h"
 #include "nmv-conf-keys.h"
+#include "nmv-layout-selector.h"
 #include <gtksourceviewmm/styleschememanager.h>
 
 using nemiver::common::DynamicModuleManager;
@@ -64,7 +65,8 @@ class PreferencesDialog::Priv {
     };
 
 public:
-    IWorkbench &workbench;
+    IPerspective &perspective;
+    LayoutManager &layout_manager;
     //source directories property widgets
     vector<UString> source_dirs;
     Glib::RefPtr<Gtk::ListStore> list_store;
@@ -80,6 +82,7 @@ public:
     StyleModelColumns m_style_columns;
     Gtk::CellRendererText m_style_name_renderer;
     Gtk::HBox *custom_font_box;
+    Gtk::Box *layout_box;
     Gtk::CheckButton *show_lines_check_button;
     Gtk::CheckButton *launch_terminal_check_button;
     Gtk::CheckButton *highlight_source_check_button;
@@ -93,15 +96,19 @@ public:
     Gtk::SpinButton  *default_num_asm_instrs_spin_button;
     Gtk::FileChooserButton *gdb_binary_path_chooser_button;
     Glib::RefPtr<Gtk::Builder> gtkbuilder;
+    SafePtr<LayoutSelector> layout_selector;
 
     Priv (const Glib::RefPtr<Gtk::Builder> &a_gtkbuilder,
-          IWorkbench &a_workbench) :
-        workbench (a_workbench),
+          IPerspective &a_perspective,
+          LayoutManager &a_layout_manager) :
+        perspective (a_perspective),
+        layout_manager (a_layout_manager),
         tree_view (0),
         remove_dir_button (0),
         system_font_check_button (0),
         custom_font_button (0),
         custom_font_box (0),
+        layout_box (0),
         show_lines_check_button (0),
         launch_terminal_check_button (0),
         highlight_source_check_button (0),
@@ -445,6 +452,18 @@ public:
             (sigc::mem_fun
                  (*this,
                   &PreferencesDialog::Priv::on_follow_fork_mode_toggle_signal));
+
+        // *************************************
+        // Handle the "Layout" preferences tab
+        // *************************************
+
+        layout_box = ui_utils::get_widget_from_gtkbuilder<Gtk::Box>
+            (gtkbuilder, "layoutbox");
+        THROW_IF_FAIL (layout_box);
+
+        layout_selector.reset (new LayoutSelector (layout_manager, perspective));
+        layout_box->pack_start (layout_selector->widget ());
+        layout_box->show_all_children ();
     }
 
     void collect_source_dirs ()
@@ -472,7 +491,8 @@ public:
 
     IConfMgr& conf_manager () const
     {
-        IConfMgrSafePtr conf_mgr = workbench.get_configuration_manager ();
+        IConfMgrSafePtr conf_mgr = perspective.get_workbench ()
+            .get_configuration_manager ();
         THROW_IF_FAIL (conf_mgr);
         return *conf_mgr;
     }
@@ -786,13 +806,14 @@ public:
     }
 };//end PreferencesDialog
 
-PreferencesDialog::PreferencesDialog (IWorkbench &a_workbench,
+PreferencesDialog::PreferencesDialog (IPerspective &a_perspective,
+                                      LayoutManager &a_layout_manager,
                                       const UString &a_root_path) :
     Dialog (a_root_path,
             "preferencesdialog.ui",
             "preferencesdialog")
 {
-    m_priv.reset (new Priv (gtkbuilder (), a_workbench));
+    m_priv.reset (new Priv (gtkbuilder (), a_perspective, a_layout_manager));
     m_priv->update_widget_from_conf ();
 }
 
diff --git a/src/persp/dbgperspective/nmv-preferences-dialog.h b/src/persp/dbgperspective/nmv-preferences-dialog.h
index 7407a4e..c2f2a84 100644
--- a/src/persp/dbgperspective/nmv-preferences-dialog.h
+++ b/src/persp/dbgperspective/nmv-preferences-dialog.h
@@ -33,7 +33,8 @@ using nemiver::common::UString;
 
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 
-class IWorkbench;
+class IPerspective;
+class LayoutManager;
 class PreferencesDialog : public Dialog {
 
     class Priv;
@@ -42,7 +43,8 @@ class PreferencesDialog : public Dialog {
     PreferencesDialog ();
 
 public:
-    PreferencesDialog (IWorkbench &a_workbench,
+    PreferencesDialog (IPerspective &a_perspective,
+                       LayoutManager &a_layout_manager,
                        const UString &a_root_path);
     virtual ~PreferencesDialog ();
     const std::vector<UString>& source_directories () const;
diff --git a/src/persp/dbgperspective/ui/Makefile.am b/src/persp/dbgperspective/ui/Makefile.am
index 2b42c3f..5091f59 100644
--- a/src/persp/dbgperspective/ui/Makefile.am
+++ b/src/persp/dbgperspective/ui/Makefile.am
@@ -1,6 +1,5 @@
 PLUGIN_NAME=dbgperspective
-uifiles = bodycontainer.ui \
-runprogramdialog.ui \
+uifiles = runprogramdialog.ui \
 proclistdialog.ui \
 loadcoredialog.ui \
 savedsessionsdialog.ui \
diff --git a/src/persp/dbgperspective/ui/preferencesdialog.ui b/src/persp/dbgperspective/ui/preferencesdialog.ui
index 4e924e6..2c76596 100644
--- a/src/persp/dbgperspective/ui/preferencesdialog.ui
+++ b/src/persp/dbgperspective/ui/preferencesdialog.ui
@@ -849,6 +849,29 @@
                 <property name="tab_fill">False</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkVBox" id="layoutbox">
+                <property name="visible">True</property>
+                <property name="border_width">6</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label19">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Layout</property>
+              </object>
+              <packing>
+                <property name="position">3</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
diff --git a/src/persp/nmv-i-perspective.h b/src/persp/nmv-i-perspective.h
index bc7d0fd..c0440f1 100644
--- a/src/persp/nmv-i-perspective.h
+++ b/src/persp/nmv-i-perspective.h
@@ -140,6 +140,10 @@ public:
     /// about its activation state (whether it is activated or not).
     virtual sigc::signal<void, bool>& activated_signal () = 0;
 
+    /// This signal is emited to notify the workbench when the
+    /// layout of the perspective changes.
+    virtual sigc::signal<void>& layout_changed_signal () = 0;
+
     /// @}
 
 };//end class IPerspective
diff --git a/src/uicommon/Makefile.am b/src/uicommon/Makefile.am
index 1cca586..b321a09 100644
--- a/src/uicommon/Makefile.am
+++ b/src/uicommon/Makefile.am
@@ -17,7 +17,12 @@ $(h)/nmv-popup-tip.h \
 $(h)/nmv-terminal.cc \
 $(h)/nmv-terminal.h \
 $(h)/nmv-source-editor.cc \
-$(h)/nmv-source-editor.h
+$(h)/nmv-source-editor.h \
+$(h)/nmv-layout.h \
+$(h)/nmv-layout-manager.cc \
+$(h)/nmv-layout-manager.h \
+$(h)/nmv-layout-selector.cc \
+$(h)/nmv-layout-selector.h
 
 if BUILD_MEMORYVIEW
 memoryview_sources = \
@@ -36,5 +41,6 @@ libnemiveruicommon_la_CFLAGS= -fPIC -DPIC
 INCLUDES= NEMIVERUICOMMON_CFLAGS@ \
 -I$(abs_top_srcdir) \
 -I$(abs_top_srcdir)/src \
--I$(abs_top_srcdir)/src/uicommon
-
+-I$(abs_top_srcdir)/src/confmgr \
+-I$(abs_top_srcdir)/src/uicommon \
+-I$(abs_top_srcdir)/src/workbench
diff --git a/src/uicommon/nmv-layout-manager.cc b/src/uicommon/nmv-layout-manager.cc
new file mode 100644
index 0000000..e288571
--- /dev/null
+++ b/src/uicommon/nmv-layout-manager.cc
@@ -0,0 +1,157 @@
+//Author: Fabien Parent
+/*
+ *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 <gtkmm/widget.h>
+#include "nmv-layout-manager.h"
+#include "nmv-layout.h"
+#include "persp/nmv-i-perspective.h"
+#include "common/nmv-exception.h"
+
+using namespace std;
+using namespace nemiver::common;
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+/// \brief Manages Layouts
+///
+/// The LayoutManager is used to load/unload layout inside a IPerspective.
+struct LayoutManager::Priv {
+    map<UString, LayoutSafePtr> layouts_map;
+    Layout *layout;
+    sigc::signal<void> layout_changed_signal;
+
+    Priv () :
+        layout (0)
+    {
+    }
+};
+
+LayoutManager::LayoutManager () :
+    m_priv (new Priv)
+{
+}
+
+LayoutManager::~LayoutManager ()
+{
+    LOG_D ("deleted", "destructor-domain");
+}
+
+/// \brief Register a layout inside the LayoutManager
+///
+/// A Layout registered can be loaded and unloaded by the layout manager.
+/// This layout will also be displayed in the Layout Selector to let the user
+/// use it.
+///
+/// \param a_layout Layout to register
+void
+LayoutManager::register_layout (const LayoutSafePtr &a_layout)
+{
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (a_layout);
+
+    UString layout_identifier = a_layout->identifier ();
+    THROW_IF_FAIL (!m_priv->layouts_map.count (layout_identifier));
+
+    m_priv->layouts_map[layout_identifier] =  a_layout;
+}
+
+/// \brief Load a layout.
+///
+/// Unload the previous layout and load a new layout inside
+/// the perspective.
+///
+/// \param a_layout Identifier of the layout to load
+/// \param a_perspective Perspective loading the layout
+void
+LayoutManager::load_layout (const UString &a_identifier,
+                            IPerspective &a_perspective)
+{
+    THROW_IF_FAIL (m_priv);
+
+    if (!is_layout_registered (a_identifier)) {
+        LOG_ERROR ("Trying to load a unregistered layout with the identifier: "
+                   << a_identifier);
+        return;
+    }
+
+    if (m_priv->layout) {
+        m_priv->layout->save_configuration ();
+        m_priv->layout->do_cleanup_layout ();
+    }
+
+    m_priv->layout = m_priv->layouts_map[a_identifier].get ();
+    THROW_IF_FAIL (m_priv->layout);
+
+    m_priv->layout->do_lay_out (a_perspective);
+    m_priv->layout_changed_signal.emit ();
+}
+
+/// \brief emited when the layout is changed
+sigc::signal<void>&
+LayoutManager::layout_changed_signal () const
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->layout_changed_signal;
+}
+
+/// \brief check if the given layout had been registered in the
+/// layout manager.
+///
+/// \param a_layout_identifier Identifier of the layout
+/// \return true is the layout is registered in the LayoutManager
+bool
+LayoutManager::is_layout_registered (const UString &a_layout_identifier) const
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->layouts_map.count (a_layout_identifier);
+}
+
+/// \brief gets the loaded layout
+/// \return loaded layout
+Layout*
+LayoutManager::layout () const
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->layout;
+}
+
+/// \brief gets the layouts registered
+/// \return layouts registered
+std::vector<Layout*>
+LayoutManager::layouts () const
+{
+    THROW_IF_FAIL (m_priv);
+
+    std::vector<Layout*> layouts;
+    for (map<UString, LayoutSafePtr>::const_iterator i = m_priv->layouts_map.begin ();
+         i != m_priv->layouts_map.end ();
+         ++i) {
+        layouts.push_back (i->second.get ());
+    }
+
+    return layouts;
+}
+
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/uicommon/nmv-layout-manager.h b/src/uicommon/nmv-layout-manager.h
new file mode 100644
index 0000000..bf735e8
--- /dev/null
+++ b/src/uicommon/nmv-layout-manager.h
@@ -0,0 +1,74 @@
+//Author: Fabien Parent
+/*
+ *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 __NMV_LAYOUT_MANAGER_H__
+#define __NMV_LAYOUT_MANAGER_H__
+
+#include "common/nmv-safe-ptr-utils.h"
+#include "common/nmv-ustring.h"
+#include "nmv-layout.h"
+#include <vector>
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+using nemiver::common::SafePtr;
+using nemiver::common::UString;
+
+class Layout;
+class IPerspective;
+
+class LayoutManager {
+    //non copyable
+    LayoutManager (const LayoutManager&);
+    LayoutManager& operator= (const LayoutManager&);
+
+    struct Priv;
+    SafePtr<Priv> m_priv;
+
+public:
+    LayoutManager ();
+
+    void register_layout (const LayoutSafePtr &a_layout);
+
+    void load_layout (const UString &a_layout, IPerspective &a_perspective);
+
+    Layout* layout () const;
+
+    std::vector<Layout*> layouts () const;
+
+    bool is_layout_registered (const UString &a_layout_identifier) const;
+
+    /// \name signals
+    /// @{
+
+    sigc::signal<void>& layout_changed_signal () const;
+
+    /// @}
+
+    virtual ~LayoutManager ();
+};
+
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif //__NMV_LAYOUT_MANAGER_H__
diff --git a/src/uicommon/nmv-layout-selector.cc b/src/uicommon/nmv-layout-selector.cc
new file mode 100644
index 0000000..bf507ac
--- /dev/null
+++ b/src/uicommon/nmv-layout-selector.cc
@@ -0,0 +1,193 @@
+//Author: Fabien Parent
+/*
+ *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 "nmv-layout-selector.h"
+#include "nmv-layout-manager.h"
+#include "nmv-layout.h"
+#include "nmv-ui-utils.h"
+#include "common/nmv-exception.h"
+#include "persp/nmv-i-perspective.h"
+#include "confmgr/nmv-i-conf-mgr.h"
+#include "confmgr/nmv-conf-keys.h"
+
+#include <gtkmm/treemodel.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/liststore.h>
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+struct LayoutModelColumns : public Gtk::TreeModel::ColumnRecord {
+    LayoutModelColumns ()
+    {
+        add (is_selected);
+        add (name);
+        add (description);
+        add (identifier);
+    }
+
+    Gtk::TreeModelColumn<bool> is_selected;
+    Gtk::TreeModelColumn<Glib::ustring> name;
+    Gtk::TreeModelColumn<Glib::ustring> description;
+    Gtk::TreeModelColumn<Glib::ustring> identifier;
+};
+
+/// \brief Widget to change the layout of a perspective
+struct LayoutSelector::Priv {
+    IPerspective &perspective;
+    Gtk::TreeView treeview;
+    LayoutModelColumns model;
+    LayoutManager &layout_manager;
+
+    void
+    on_layout_toggled (const Glib::ustring &a_str)
+    {
+        Glib::RefPtr<Gtk::TreeModel> tree_model = treeview.get_model ();
+        THROW_IF_FAIL (tree_model);
+
+        Gtk::TreePath path (a_str);
+        Gtk::TreeModel::iterator iter = tree_model->get_iter (path);
+        THROW_IF_FAIL (iter);
+
+        (*iter)[model.is_selected] = true;
+
+        // de-select every other layout but the one the user just selected.
+        for (Gtk::TreeModel::iterator i = tree_model->children ().begin ();
+             i != tree_model->children ().end ();
+             ++i) {
+            if (*i == *iter)
+                continue;
+
+            (*i)[model.is_selected] = false;
+        }
+
+        UString identifier = (Glib::ustring) (*iter)[model.identifier];
+        layout_manager.load_layout (identifier, perspective);
+
+        NEMIVER_TRY
+        IConfMgrSafePtr conf_mgr = perspective.get_workbench ()
+            .get_configuration_manager ();
+        THROW_IF_FAIL (conf_mgr);
+        conf_mgr->set_key_value (CONF_KEY_DBG_PERSPECTIVE_LAYOUT, identifier);
+        NEMIVER_CATCH
+    }
+
+    void
+    on_cell_rendering (Gtk::CellRenderer *a_renderer,
+                      const Gtk::TreeModel::iterator &a_iter)
+    {
+        THROW_IF_FAIL (a_renderer);
+        THROW_IF_FAIL (a_iter);
+
+        Gtk::CellRendererText *text_renderer =
+            dynamic_cast<Gtk::CellRendererText*> (a_renderer);
+        THROW_IF_FAIL (text_renderer);
+
+        text_renderer->property_markup () =
+            Glib::ustring::compose (
+                        "<b>%1</b>\n%2",
+                        Glib::Markup::escape_text ((*a_iter)[model.name]),
+                        Glib::Markup::escape_text ((*a_iter)[model.description]));
+    }
+
+    Priv (LayoutManager &a_layout_manager, IPerspective &a_perspective) :
+        perspective (a_perspective),
+        layout_manager (a_layout_manager)
+    {
+        init ();
+    }
+
+    void
+    init ()
+    {
+        treeview.set_headers_visible (false);
+
+        Glib::RefPtr<Gtk::ListStore> store = Gtk::ListStore::create (model);
+        treeview.set_model (store);
+
+        treeview.append_column_editable ("", model.is_selected);
+        treeview.append_column ("", model.name);
+
+        Gtk::CellRendererToggle *toggle_renderer =
+            dynamic_cast<Gtk::CellRendererToggle*>
+                (treeview.get_column_cell_renderer (0));
+        THROW_IF_FAIL (toggle_renderer);
+        toggle_renderer->set_radio (true);
+        toggle_renderer->signal_toggled ().connect
+            (sigc::mem_fun (*this, &LayoutSelector::Priv::on_layout_toggled));
+
+        Gtk::CellRenderer *renderer = dynamic_cast<Gtk::CellRendererText*>
+            (treeview.get_column_cell_renderer (1));
+        THROW_IF_FAIL (renderer);
+
+        treeview.get_column (1)->set_cell_data_func (*renderer, sigc::mem_fun
+            (*this, &LayoutSelector::Priv::on_cell_rendering));
+
+        fill_tree_view (store);
+    }
+
+    void
+    fill_tree_view (const Glib::RefPtr<Gtk::ListStore> &a_store)
+    {
+        Layout* current_layout = layout_manager.layout ();
+        std::vector<Layout*> layouts = layout_manager.layouts ();
+        for (std::vector<Layout*>::iterator i = layouts.begin ();
+             i != layouts.end ();
+             ++i) {
+            THROW_IF_FAIL (*i);
+
+            Gtk::TreeModel::Row row = *a_store->append ();
+            row[model.is_selected] = false;
+            row[model.name] = (*i)->name ();
+            row[model.description] = (*i)->description ();
+            row[model.identifier] = (*i)->identifier ();
+
+            if (current_layout
+                && (*i)->identifier () == current_layout->identifier ()) {
+                row[model.is_selected] = true;
+            }
+        }
+    }
+};//end struct LayoutSelector::Priv
+
+LayoutSelector::LayoutSelector (LayoutManager &a_layout_manager,
+                                IPerspective &a_perspective) :
+    m_priv (new Priv (a_layout_manager, a_perspective))
+{
+}
+
+/// \brief gets the widget
+/// \return the widget
+Gtk::Widget&
+LayoutSelector::widget () const
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->treeview;
+}
+
+LayoutSelector::~LayoutSelector ()
+{
+    LOG_D ("deleted", "destructor-domain");
+}
+
+NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/uicommon/nmv-layout-selector.h b/src/uicommon/nmv-layout-selector.h
new file mode 100644
index 0000000..b44951b
--- /dev/null
+++ b/src/uicommon/nmv-layout-selector.h
@@ -0,0 +1,58 @@
+//Author: Fabien Parent
+/*
+ *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 __NMV_LAYOUT_SELECTOR_H__
+#define __NMV_LAYOUT_SELECTOR_H__
+
+#include "common/nmv-safe-ptr-utils.h"
+
+namespace Gtk {
+    class Widget;
+}
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+using nemiver::common::SafePtr;
+
+class LayoutManager;
+class IPerspective;
+
+class LayoutSelector {
+    LayoutSelector (const LayoutSelector&);
+    LayoutSelector& operator= (const LayoutSelector&);
+
+    struct Priv;
+    SafePtr<Priv> m_priv;
+
+public:
+    LayoutSelector (LayoutManager&, IPerspective&);
+
+    Gtk::Widget& widget () const;
+
+    virtual ~LayoutSelector ();
+};
+
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif //__NMV_LAYOUT_SELECTOR_H__
diff --git a/src/uicommon/nmv-layout.h b/src/uicommon/nmv-layout.h
new file mode 100644
index 0000000..46635ff
--- /dev/null
+++ b/src/uicommon/nmv-layout.h
@@ -0,0 +1,109 @@
+//Author: Fabien Parent
+/*
+ *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 __NMV_LAYOUT_H__
+#define __NMV_LAYOUT_H__
+
+#include "common/nmv-ustring.h"
+#include "common/nmv-object.h"
+#include "common/nmv-safe-ptr-utils.h"
+
+namespace Gtk {
+    class Widget;
+}//end namespace Gtk
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+using namespace common;
+
+class IPerspective;
+class Layout;
+typedef SafePtr<Layout, ObjectRef, ObjectUnref> LayoutSafePtr;
+
+/// \brief The base class for Layouts
+///
+/// Perspectives can use the LayoutManager to manage different Layouts.
+/// The LayoutManager handle object that inherit from the class Layout.
+class Layout : public Object {
+    //non copyable
+    Layout (const Layout&);
+    Layout& operator= (const Layout&);
+
+protected:
+    Layout () {}
+
+public:
+    /// \brief initialize the layout
+    /// \param a_perspective The associated perspective.
+    virtual void do_lay_out (IPerspective &a_perspective) = 0;
+
+    /// \brief clean-up the layout
+    ///
+    /// Must be called before initializing a new layout for a perspective.
+    virtual void do_cleanup_layout () = 0;
+
+    /// \brief gets the layout unique identifier
+    /// \return layout unique identifier
+    virtual const UString& identifier () const = 0;
+
+    /// \brief gets the layout name
+    /// \return layout name
+    virtual const UString& name () const = 0;
+
+    /// \brief gets the layout description
+    /// \return layout description
+    virtual const UString& description () const = 0;
+
+    /// \brief gets the layout container widget
+    /// \return layout container widget
+    virtual Gtk::Widget* widget () const = 0;
+
+    /// \brief Initialize the layout
+    virtual void do_init () = 0;
+
+    /// \brief save the configuration of the layout
+    virtual void save_configuration () = 0;
+
+    /// \brief activate a view
+    /// \param a_view_identifier The view to activate
+    virtual void activate_view (int a_view_identifier) = 0;
+
+    /// \brief add a view to the layout
+    /// \param a_widget Widget of the view to add to the layout
+    /// \param a_title Title of the view (will appears in notebook label, ...)
+    /// \param a_index Unique identifier of the view to add to the layout
+    virtual void add_view (Gtk::Widget &a_widget,
+                           const UString &a_title,
+                           int a_index) = 0;
+
+    /// \brief remove a view from the layout
+    /// \param a_index Unique identifier of the view to remove from the layout
+    virtual void remove_view (int a_index) = 0;
+
+    virtual ~Layout () {}
+};
+
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif //__NMV_LAYOUT_H__
diff --git a/src/workbench/nmv-workbench.cc b/src/workbench/nmv-workbench.cc
index b904753..af893d0 100644
--- a/src/workbench/nmv-workbench.cc
+++ b/src/workbench/nmv-workbench.cc
@@ -85,6 +85,7 @@ private:
     void on_about_menu_item_action ();
     void on_contents_menu_item_action ();
     void on_shutting_down_signal ();
+    void on_perspective_layout_changed_signal (IPerspectiveSafePtr);
     //************************
     //</slots (signal callbacks)>
     //************************
@@ -101,6 +102,7 @@ private:
                                Gtk::Widget *a_body);
     bool remove_perspective_body (IPerspectiveSafePtr &a_perspective);
     void remove_all_perspective_bodies ();
+    void disconnect_all_perspective_signals ();
     void select_perspective (IPerspectiveSafePtr &a_perspective);
 
     void save_window_geometry ();
@@ -329,6 +331,7 @@ Workbench::Workbench (DynamicModule *a_dynmod) :
 Workbench::~Workbench ()
 {
     remove_all_perspective_bodies ();
+    disconnect_all_perspective_signals ();
     LOG_D ("delete", "destructor-domain");
 }
 
@@ -421,6 +424,11 @@ Workbench::do_init (Gtk::Main &a_main)
                 if (perspective) {
                     m_priv->perspectives.push_front (perspective);
                     perspective->do_init (workbench);
+                    perspective->layout_changed_signal ().connect
+                        (sigc::bind<IPerspectiveSafePtr> (sigc::mem_fun
+                            (*this,
+                            &Workbench::on_perspective_layout_changed_signal),
+                        perspective));
                     perspective->edit_workbench_menu ();
                     toolbars.clear ();
                     perspective->get_toolbars (toolbars);
@@ -814,6 +822,25 @@ Workbench::add_perspective_body (IPerspectiveSafePtr &a_perspective,
         m_priv->bodies_container->insert_page (*a_body, -1);
 }
 
+void
+Workbench::on_perspective_layout_changed_signal
+        (IPerspectiveSafePtr a_perspective)
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    THROW_IF_FAIL (m_priv);
+    THROW_IF_FAIL (m_priv->bodies_container);
+
+    if (!a_perspective) {return;}
+
+    int page = m_priv->bodies_index_map[a_perspective.get ()];
+
+    m_priv->bodies_container->remove_page (page);
+    m_priv->bodies_container->insert_page (*a_perspective->get_body (), page);
+
+    select_perspective (a_perspective);
+}
+
 bool
 Workbench::remove_perspective_body (IPerspectiveSafePtr &a_perspective)
 {
@@ -881,6 +908,19 @@ Workbench::remove_all_perspective_bodies ()
 }
 
 void
+Workbench::disconnect_all_perspective_signals ()
+{
+    LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+    list<IPerspectiveSafePtr>::iterator it;
+    for (it = m_priv->perspectives.begin ();
+         it != m_priv->perspectives.end ();
+         ++it) {
+        (*it)->layout_changed_signal ().clear ();
+    }
+}
+
+void
 Workbench::select_perspective (IPerspectiveSafePtr &a_perspective)
 {
     LOG_FUNCTION_SCOPE_NORMAL_DD;



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