summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-03-08 21:44:52 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-03-08 21:46:19 (GMT)
commit235b34006d734d55333a182ffd8bbe7fbf8f54bc (patch)
treef1c8f75391537c8c187aea46c16b3d2642c92107
parent02e978d601cdcf2ea9bb39ae21207c3b97d16e22 (diff)
Loaded a dynamic list of dockable panels in the View menu.
-rw-r--r--ChangeLog51
-rw-r--r--plugins/pychrysa/gui/panels/panel.c43
-rw-r--r--plugins/python/welcome/panel.py2
-rw-r--r--src/analysis/project.c2
-rw-r--r--src/gtkext/gtkdockable.c35
-rw-r--r--src/gtkext/gtkdockable.h5
-rw-r--r--src/gtkext/gtkdockstation.c183
-rw-r--r--src/gtkext/gtkdockstation.h9
-rw-r--r--src/gtkext/gtkviewpanel.c4
-rw-r--r--src/gui/editem.c21
-rw-r--r--src/gui/editem.h3
-rw-r--r--src/gui/menus/menubar.c2
-rw-r--r--src/gui/menus/project.c2
-rw-r--r--src/gui/menus/view.c168
-rw-r--r--src/gui/panels/bookmarks.c5
-rw-r--r--src/gui/panels/glance.c10
-rw-r--r--src/gui/panels/history.c7
-rw-r--r--src/gui/panels/log.c22
-rw-r--r--src/gui/panels/panel-int.h38
-rw-r--r--src/gui/panels/panel.c929
-rw-r--r--src/gui/panels/panel.h46
-rw-r--r--src/gui/panels/regedit.c7
-rw-r--r--src/gui/panels/strings.c11
-rw-r--r--src/gui/panels/symbols.c13
24 files changed, 1111 insertions, 507 deletions
diff --git a/ChangeLog b/ChangeLog
index 09dc5d8..ca1655f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,54 @@
+16-03-08 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/pychrysa/gui/panels/panel.c:
+ Register new constants for panels.
+
+ * plugins/python/welcome/panel.py:
+ * src/analysis/project.c:
+ Update code.
+
+ * src/gtkext/gtkdockable.c:
+ * src/gtkext/gtkdockable.h:
+ Provide references of dockable items for UI.
+
+ * src/gtkext/gtkdockstation.c:
+ * src/gtkext/gtkdockstation.h:
+ Inherit from GtkNotebook directly for dock stations. Dock and undock
+ widgets.
+
+ * src/gtkext/gtkviewpanel.c:
+ Disable some code.
+
+ * src/gui/editem.c:
+ * src/gui/editem.h:
+ Provide editor item name for external usage.
+
+ * src/gui/menus/menubar.c:
+ Store the global accelerator group.
+
+ * src/gui/menus/project.c:
+ Typo.
+
+ * src/gui/menus/view.c:
+ Load a dynamic list of dockable panels in the View menu. Dock and undock
+ panels on demand.
+
+ * src/gui/panels/bookmarks.c:
+ * src/gui/panels/glance.c:
+ * src/gui/panels/history.c:
+ * src/gui/panels/log.c:
+ Update code.
+
+ * src/gui/panels/panel-int.h:
+ * src/gui/panels/panel.c:
+ * src/gui/panels/panel.h:
+ Give a personality to each panel. Rewrite the tree of docked widgets.
+
+ * src/gui/panels/regedit.c:
+ * src/gui/panels/strings.c:
+ * src/gui/panels/symbols.c:
+ Update code.
+
16-03-05 Cyrille Bagard <nocbos@gmail.com>
* src/arch/arm/v7/helpers.h:
diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c
index 3170a66..8046c0e 100644
--- a/plugins/pychrysa/gui/panels/panel.c
+++ b/plugins/pychrysa/gui/panels/panel.c
@@ -32,6 +32,7 @@
#include "../editem.h"
+#include "../../helpers.h"
#include "../../quirks.h"
@@ -42,6 +43,9 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds);
/* Place un panneau dans l'ensemble affiché. */
static PyObject *py_panel_item_dock(PyObject *, PyObject *);
+/* Définit les constantes pour les panneaux. */
+static bool py_panel_item_define_constants(PyTypeObject *);
+
/******************************************************************************
@@ -60,6 +64,7 @@ static PyObject *py_panel_item_dock(PyObject *, PyObject *);
static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds)
{
+ unsigned long personality; /* Nature du panneau */
const char *name; /* Désignation humaine */
const char *lname; /* Nom version longue */
PyGObject *widget; /* Composant visuel du panneau */
@@ -67,10 +72,10 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds)
int ret; /* Bilan de lecture des args. */
GEditorItem *item; /* Elément de l'éditeur */
- ret = PyArg_ParseTuple(args, "ssOs", &name, &lname, &widget, &path);
+ ret = PyArg_ParseTuple(args, "kssOs", &personality, &name, &lname, &widget, &path);
if (!ret) return -1;
- item = g_panel_item_new(get_internal_ref(), name, lname,
+ item = g_panel_item_new(personality, get_internal_ref(), name, lname,
GTK_WIDGET(pygobject_get(widget)), path);
/* Enregistrement auprès de PyGObject */
@@ -161,6 +166,37 @@ PyTypeObject *get_python_panel_item_type(void)
/******************************************************************************
* *
+* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes pour les panneaux. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_panel_item_define_constants(PyTypeObject *obj_type)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ result &= PyDict_AddIntMacro(obj_type, PIP_INVALID);
+
+ result &= PyDict_AddIntMacro(obj_type, PIP_SINGLETON);
+ result &= PyDict_AddIntMacro(obj_type, PIP_BINARY_VIEW);
+ result &= PyDict_AddIntMacro(obj_type, PIP_OTHER);
+
+ result &= PyDict_AddIntMacro(obj_type, PIP_COUNT);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : module = module dont la définition est à compléter. *
* *
* Description : Prend en charge l'objet 'pychrysalide.gui.panels.PanelItem'. *
@@ -185,6 +221,9 @@ bool register_python_panel_item(PyObject *module)
if (PyType_Ready(py_panel_item_type) != 0)
return false;
+ if (!py_panel_item_define_constants(py_panel_item_type))
+ return false;
+
Py_INCREF(py_panel_item_type);
ret = PyModule_AddObject(module, "PanelItem", (PyObject *)py_panel_item_type);
if (ret != 0) return false;
diff --git a/plugins/python/welcome/panel.py b/plugins/python/welcome/panel.py
index 811f008..7b46c57 100644
--- a/plugins/python/welcome/panel.py
+++ b/plugins/python/welcome/panel.py
@@ -19,7 +19,7 @@ class WelcomePanel(PanelItem):
content = self._build_panel_content()
- super(WelcomePanel, self).__init__('Welcome', 'First commands', content, 'M')
+ super(WelcomePanel, self).__init__(PanelItem.PIP_SINGLETON, 'Welcome', 'First commands', content, 'N')
def _build_panel_content(self):
diff --git a/src/analysis/project.c b/src/analysis/project.c
index b787262..623779b 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -666,7 +666,7 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina
name = g_loaded_binary_get_name(binary, false);
lname = g_loaded_binary_get_name(binary, true);
- loaded->item = g_panel_item_new(project->ref, name, lname, scroll, "M");
+ loaded->item = g_panel_item_new(PIP_BINARY_VIEW, project->ref, name, lname, scroll, "N");
/* Enregistrement dans le projet */
diff --git a/src/gtkext/gtkdockable.c b/src/gtkext/gtkdockable.c
index 954b651..98b1a04 100644
--- a/src/gtkext/gtkdockable.c
+++ b/src/gtkext/gtkdockable.c
@@ -241,7 +241,7 @@ bool gtk_dockable_can_be_closed(const GtkDockable *dockable)
* *
******************************************************************************/
-GtkWidget *gtk_dockable_get_widget(GtkDockable *dockable)
+GtkWidget *gtk_dockable_build_widget(GtkDockable *dockable)
{
GtkWidget *result; /* Composant à retourner */
GtkDockableIface *iface; /* Interface utilisée */
@@ -286,6 +286,39 @@ GtkWidget *gtk_dockable_get_widget(GtkDockable *dockable)
/******************************************************************************
* *
* Paramètres : dockable = instance GTK dont l'interface est à consulter. *
+* support = composant à partir duquel décrocher ou NULL. [OUT]*
+* *
+* Description : Fournit tous les éléments pour un retrait graphique. *
+* *
+* Retour : Composant graphique à décrocher. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GtkWidget *gtk_dockable_decompose(GtkDockable *dockable, GtkWidget **support)
+{
+ GtkWidget *result; /* Composant à retourner */
+ GtkDockableIface *iface; /* Interface utilisée */
+
+ iface = GTK_DOCKABLE_GET_IFACE(dockable);
+
+ result = iface->get_widget(dockable);
+
+ if (iface->can_search)
+ result = gtk_widget_get_parent(result); /* GtkBox */
+
+ if (support != NULL)
+ *support = gtk_widget_get_parent(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dockable = instance GTK dont l'interface est à consulter. *
* built = composant graphique d'encapsulation mis en place. *
* reveal = détermine l'action à mener. *
* *
diff --git a/src/gtkext/gtkdockable.h b/src/gtkext/gtkdockable.h
index e939fad..31a3310 100644
--- a/src/gtkext/gtkdockable.h
+++ b/src/gtkext/gtkdockable.h
@@ -62,7 +62,10 @@ const char *gtk_dockable_get_name(const GtkDockable *);
const char *gtk_dockable_get_desc(const GtkDockable *);
/* Fournit le composant graphique intégrable dans un ensemble. */
-GtkWidget *gtk_dockable_get_widget(GtkDockable *);
+GtkWidget *gtk_dockable_build_widget(GtkDockable *);
+
+/* Fournit tous les éléments pour un retrait graphique. */
+GtkWidget *gtk_dockable_decompose(GtkDockable *, GtkWidget **);
/* Révèle ou cache la zone de recherches. */
void gtk_dockable_toggle_revealer(GtkDockable *, GtkWidget *, gboolean);
diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c
index e10e55f..35006ef 100644
--- a/src/gtkext/gtkdockstation.c
+++ b/src/gtkext/gtkdockstation.c
@@ -57,7 +57,7 @@ static void on_toggle_revealer(GtkToggleButton *, GtkDockStation *);
/* Détermine le type du composant d'affichage concentré. */
-G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_BOX)
+G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_NOTEBOOK)
/******************************************************************************
@@ -115,53 +115,14 @@ static void gtk_dock_station_class_init(GtkDockStationClass *class)
static void gtk_dock_station_init(GtkDockStation *station)
{
- GtkWidget *eventbox; /* Réceptacle actif */
+ GtkNotebook *notebook; /* Autre version du composant */
GtkWidget *hbox; /* Division supérieure */
GtkWidget *button; /* Bouton de contrôle */
- GtkWidget *image; /* Image associée */
- gtk_orientable_set_orientation(GTK_ORIENTABLE(station), GTK_ORIENTATION_VERTICAL);
+ notebook = GTK_NOTEBOOK(station);
- eventbox = gtk_event_box_new();
- gtk_widget_show(eventbox);
- //gtk_box_pack_start(GTK_BOX(station), eventbox, FALSE, TRUE, 0);
-
- hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_widget_show(hbox);
- gtk_container_add(GTK_CONTAINER(eventbox), hbox);
-
- station->title = GTK_LABEL(qck_create_label(NULL, NULL, "<b>titre</b>"));
- gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(station->title), TRUE, TRUE, 0);
- gtk_label_set_use_markup(station->title, TRUE);
-
- button = gtk_button_new();
- gtk_widget_show(button);
- gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
- gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
-
- image = gtk_image_new_from_icon_name("gtk-media-play", GTK_ICON_SIZE_MENU);
- gtk_widget_show(image);
- gtk_container_add(GTK_CONTAINER(button), image);
- gtk_widget_set_size_request(image, 10, 10);
-
- button = gtk_button_new();
- gtk_widget_show(button);
- gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
- gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
-
- image = gtk_image_new_from_icon_name("gtk-close", GTK_ICON_SIZE_MENU);
- gtk_widget_show(image);
- gtk_container_add(GTK_CONTAINER(button), image);
- gtk_widget_set_size_request(image, 10, 10);
-
-
-
-
- station->notebook = GTK_NOTEBOOK(gtk_notebook_new());
- gtk_widget_show(GTK_WIDGET(station->notebook));
- gtk_box_pack_start(GTK_BOX(station), GTK_WIDGET(station->notebook), TRUE, TRUE, 0);
- gtk_notebook_set_show_border(station->notebook, FALSE);
- gtk_notebook_set_scrollable(station->notebook, TRUE);
+ gtk_notebook_set_show_border(notebook, FALSE);
+ gtk_notebook_set_scrollable(notebook, TRUE);
/* Définition de la zone de contrôle */
@@ -188,9 +149,9 @@ static void gtk_dock_station_init(GtkDockStation *station)
gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
- gtk_notebook_set_action_widget(station->notebook, hbox, GTK_PACK_END);
+ gtk_notebook_set_action_widget(notebook, hbox, GTK_PACK_END);
- g_signal_connect(station->notebook, "switch-page",
+ g_signal_connect(notebook, "switch-page",
G_CALLBACK(gtk_dock_station_switch_panel), station);
}
@@ -267,10 +228,8 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p
/******************************************************************************
* *
-* Paramètres : station = plateforme GTK à compléter. *
-* widget = nouvel élément à intégrer. *
-* caption = intitulé court à afficher sur les onglets. *
-* desc = intitulé long pour le titre et la description. *
+* Paramètres : station = plateforme GTK à compléter. *
+* dockable = nouvel élément à intégrer. *
* *
* Description : Ajoute un paquet d'informations à l'affichage centralisé. *
* *
@@ -279,7 +238,8 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p
* Remarques : - *
* *
******************************************************************************/
-
+#include "gtkviewpanel.h"
+#include "../gui/panels/history.h"
void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockable)
{
GtkWidget *widget; /* Composant GTK à intégrer */
@@ -288,10 +248,34 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl
size_t max; /* Taille maximale des titres */
char *str; /* Titre des prochaines fois */
GtkWidget *label; /* Etiquette d'onglet */
+ GtkNotebook *notebook; /* Autre version du composant */
/* Récupération des éléments utiles */
- widget = gtk_dockable_get_widget(dockable);
+ widget = gtk_dockable_build_widget(dockable);
+
+
+ if (strcmp(gtk_dockable_get_name(dockable), "History") == 0)
+ {
+ GtkRequisition req;
+
+ gtk_widget_get_preferred_size(widget, &req, NULL);
+ fprintf(stderr, "Histo req :: %d x %d\n", req.width, req.height);
+
+ }
+
+ /*
+ if (!GTK_IS_SCROLLED_WINDOW(widget)
+ && (
+ strcmp(gtk_dockable_get_name(dockable), "History2") != 0
+ )
+ )
+ widget = gtk_button_new_with_label("123");
+ */
+
+ //widget = gtk_button_new_with_label("123");
+ gtk_widget_show(widget);
+
g_object_set_data(G_OBJECT(widget), "dockable", dockable);
@@ -307,24 +291,52 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl
label = qck_create_label(NULL, NULL, str);
free(str);
- if (gtk_notebook_get_n_pages(station->notebook) > 0)
- g_signal_handlers_disconnect_by_func(station->notebook,
+ notebook = GTK_NOTEBOOK(station);
+
+ if (gtk_notebook_get_n_pages(notebook) > 0)
+ g_signal_handlers_disconnect_by_func(notebook,
G_CALLBACK(gtk_dock_station_switch_panel), station);
- gtk_notebook_insert_page(station->notebook, widget, label, -1);
+ gtk_notebook_insert_page(notebook, widget, label, -1);
gtk_widget_set_tooltip_text(label, desc);
- if (gtk_notebook_get_n_pages(station->notebook) > 1)
- g_signal_connect(station->notebook, "switch-page",
+ if (gtk_notebook_get_n_pages(notebook) > 1)
+ g_signal_connect(notebook, "switch-page",
G_CALLBACK(gtk_dock_station_switch_panel), station);
/* Lancement des mises à jour */
- if (gtk_notebook_get_n_pages(station->notebook) > 1)
- gtk_notebook_set_current_page(station->notebook, -1);
+ if (gtk_notebook_get_n_pages(notebook) > 1)
+ gtk_notebook_set_current_page(notebook, -1);
+
+
+ // Renéociation des tailles
+ //gtk_widget_queue_resize(GTK_WIDGET(notebook));
+
+
+ if (false)
+ {
+ GtkRequisition req;
+
+ gtk_widget_get_preferred_size(GTK_WIDGET(notebook), &req, NULL);
+ fprintf(stderr, "=== SUPPORT req :: %d x %d\n", req.width, req.height);
+
+
+ gtk_widget_set_size_request(GTK_WIDGET(notebook), req.width, req.height);
+
+
+
+ }
+
+
- g_signal_emit_by_name(station, "dock-widget", widget);
+
+
+
+
+
+ //g_signal_emit_by_name(station, "dock-widget", widget);
}
@@ -344,32 +356,35 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl
void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *widget)
{
+ GtkNotebook *notebook; /* Autre version du composant */
gint index; /* Indice de l'onglet actif */
GtkWidget *old; /* Ancien composant */
GtkWidget *label; /* Etiquette d'onglet */
char *str; /* Titre des prochaines fois */
- index = gtk_notebook_get_current_page(station->notebook);
+ notebook = GTK_NOTEBOOK(station);
+
+ index = gtk_notebook_get_current_page(notebook);
- g_signal_handlers_disconnect_by_func(station->notebook,
+ g_signal_handlers_disconnect_by_func(notebook,
G_CALLBACK(gtk_dock_station_switch_panel), station);
- old = gtk_notebook_get_nth_page(station->notebook, index);
- label = gtk_notebook_get_tab_label(station->notebook, old);
+ old = gtk_notebook_get_nth_page(notebook, index);
+ label = gtk_notebook_get_tab_label(notebook, old);
g_object_ref(G_OBJECT(old));
g_object_ref(G_OBJECT(label));
str = g_object_get_data(G_OBJECT(old), "title");
- gtk_notebook_remove_page(station->notebook, index);
- gtk_notebook_insert_page(station->notebook, widget, label, index);
+ gtk_notebook_remove_page(notebook, index);
+ gtk_notebook_insert_page(notebook, widget, label, index);
g_object_unref(G_OBJECT(label));
g_object_set_data(G_OBJECT(widget), "title", str);
- gtk_notebook_set_current_page(station->notebook, index);
+ gtk_notebook_set_current_page(notebook, index);
- g_signal_connect(station->notebook, "switch-page",
+ g_signal_connect(notebook, "switch-page",
G_CALLBACK(gtk_dock_station_switch_panel), station);
}
@@ -378,7 +393,7 @@ void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *wid
/******************************************************************************
* *
* Paramètres : station = plateforme GTK à compléter. *
-* widget = nouvel élément à intégrer. *
+* dockable = élément existant à retirer. *
* *
* Description : Retire un paquet d'informations de l'affichage centralisé. *
* *
@@ -388,26 +403,19 @@ void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *wid
* *
******************************************************************************/
-void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget)
+void gtk_dock_station_remove_dockable(GtkDockStation *station, GtkDockable *dockable)
{
+ GtkNotebook *notebook; /* Autre version du composant */
+ GtkWidget *widget; /* Composant GTK à retirer */
gint index; /* Indice de l'onglet visé */
- gint count; /* Nombre d'onglets en place */
+ notebook = GTK_NOTEBOOK(station);
- return;
+ widget = gtk_dockable_decompose(dockable, NULL);
+ index = gtk_notebook_page_num(notebook, widget);
- index = gtk_notebook_page_num(station->notebook, widget);
-
- gtk_notebook_remove_page(station->notebook, index);
-
- count = gtk_notebook_get_n_pages(station->notebook);
-
- //gtk_notebook_set_show_tabs(station->notebook, count > 1);
-
- if (count == 0)
- gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(station))),
- GTK_WIDGET(station));
+ gtk_notebook_remove_page(notebook, index);
}
@@ -427,7 +435,7 @@ void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget)
GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index)
{
- return gtk_notebook_get_nth_page(station->notebook, index);
+ return gtk_notebook_get_nth_page(GTK_NOTEBOOK(station), index);
}
@@ -447,12 +455,15 @@ GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index)
static void on_toggle_revealer(GtkToggleButton *button, GtkDockStation *station)
{
+ GtkNotebook *notebook; /* Autre version du composant */
gint index; /* Indice de l'onglet courant */
GtkWidget *widget; /* Panneau concerné */
GtkDockable *dockable; /* Elément encapsulé */
- index = gtk_notebook_get_current_page(station->notebook);
- widget = gtk_notebook_get_nth_page(station->notebook, index);
+ notebook = GTK_NOTEBOOK(station);
+
+ index = gtk_notebook_get_current_page(notebook);
+ widget = gtk_notebook_get_nth_page(notebook, index);
dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable"));
diff --git a/src/gtkext/gtkdockstation.h b/src/gtkext/gtkdockstation.h
index d64a0b8..953ceb8 100644
--- a/src/gtkext/gtkdockstation.h
+++ b/src/gtkext/gtkdockstation.h
@@ -51,17 +51,14 @@ typedef struct _GtkDockStationClass GtkDockStationClass;
/* Station de réception pour concentration d'éléments (instance) */
struct _GtkDockStation
{
- GtkBox vbox; /* Présence obligatoire en 1er */
-
- GtkLabel *title; /* Title du support principal */
- GtkNotebook *notebook; /* Support à onglets */
+ GtkNotebook parent; /* A laisser en premier */
};
/* Station de réception pour concentration d'éléments (classe) */
struct _GtkDockStationClass
{
- GtkBoxClass parent_class; /* Présence obligatoire en 1er */
+ GtkNotebookClass parent_class; /* A laisser en premier */
/* Signaux */
@@ -86,7 +83,7 @@ void gtk_dock_station_add_dockable(GtkDockStation *, GtkDockable *);
void gtk_dock_panel_change_active_widget(GtkDockStation *, GtkWidget *);
/* Retire un paquet d'informations de l'affichage centralisé. */
-void gtk_dock_panel_remove_widget(GtkDockStation *, GtkWidget *);
+void gtk_dock_station_remove_dockable(GtkDockStation *, GtkDockable *);
/* Renvoie un composant intégré dans l'affichage centralisé. */
GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *, gint);
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index a347ad8..b7829c2 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -121,8 +121,8 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class)
widget_class->realize = gtk_view_panel_realize;
widget_class->size_allocate = gtk_view_panel_size_allocate;
widget_class->draw = gtk_view_panel_draw;
- widget_class->get_preferred_height = gtk_view_panel_get_preferred_height;
- widget_class->get_preferred_width = gtk_view_panel_get_preferred_width;
+ //widget_class->get_preferred_height = gtk_view_panel_get_preferred_height;
+ //widget_class->get_preferred_width = gtk_view_panel_get_preferred_width;
panel_class->compute_inc = gtk_view_panel_compute_scroll_inc;
diff --git a/src/gui/editem.c b/src/gui/editem.c
index 1dc77c9..f4d9d71 100644
--- a/src/gui/editem.c
+++ b/src/gui/editem.c
@@ -131,9 +131,28 @@ GObject *g_editor_item_get_global_ref(const GEditorItem *item)
* *
* Paramètres : item = instance à consulter. *
* *
+* Description : Fournit le nom humain attribué à l'élément réactif. *
+* *
+* Retour : Désignation (courte) de l'élément de l'éditeur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *g_editor_item_get_name(const GEditorItem *item)
+{
+ return item->name;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = instance à consulter. *
+* *
* Description : Fournit le composant GTK associé à l'élément réactif. *
* *
-* Retour : - *
+* Retour : Instance de composant graphique chargé. *
* *
* Remarques : - *
* *
diff --git a/src/gui/editem.h b/src/gui/editem.h
index 90b1919..08f76fa 100644
--- a/src/gui/editem.h
+++ b/src/gui/editem.h
@@ -59,6 +59,9 @@ GType g_editor_item_get_type(void);
/* Fournit l'adresse de l'espace de référencement global. */
GObject *g_editor_item_get_global_ref(const GEditorItem *);
+/* Fournit le nom humain attribué à l'élément réactif. */
+const char *g_editor_item_get_name(const GEditorItem *);
+
/* Fournit le composant GTK associé à l'élément réactif. */
GtkWidget *g_editor_item_get_widget(const GEditorItem *);
diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c
index db1905c..e2ad155 100644
--- a/src/gui/menus/menubar.c
+++ b/src/gui/menus/menubar.c
@@ -208,6 +208,8 @@ GEditorItem *g_menu_bar_new(GObject *ref, GtkAccelGroup *accgroup)
result = g_object_new(G_TYPE_MENU_BAR, NULL);
+ g_object_set_data(G_OBJECT(result), "accgroup", accgroup);
+
/* Initialisation générique */
item = G_EDITOR_ITEM(result);
diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c
index f4f6233..9e43616 100644
--- a/src/gui/menus/project.c
+++ b/src/gui/menus/project.c
@@ -66,7 +66,7 @@ static void mcb_project_remove_binary(GtkMenuItem *, GStudyProject *);
GtkWidget *build_menu_project(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
{
GtkWidget *result; /* Support à retourner */
- GtkWidget *menubar; /* Support pour éléments */
+ GtkWidget *menubar; /* Support pour éléments #1 */
GtkWidget *submenuitem; /* Sous-élément de menu #1 */
GtkWidget *deepmenubar; /* Support pour éléments #2 */
GtkWidget *deepmenuitem; /* Sous-élément de menu #2 */
diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c
index cbfa9bf..e80077a 100644
--- a/src/gui/menus/view.c
+++ b/src/gui/menus/view.c
@@ -29,12 +29,19 @@
#include "../editem-int.h"
+#include "../panels/panel.h"
#include "../../analysis/project.h"
#include "../../gtkext/easygtk.h"
#include "../../gtkext/gtkdockstation.h"
+/* Réagit avec le menu "Affichage -> Panneaux latéraux". */
+static void mcb_view_update_side_panels_list(GtkMenuItem *, GMenuBar *);
+
+/* Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". */
+static void mcb_view_change_panel_docking(GtkCheckMenuItem *, GPanelItem *);
+
/* Réagit avec le menu "Affichage -> Vue xxx". */
static void mcb_view_change_support(GtkRadioMenuItem *, GMenuBar *);
@@ -63,8 +70,9 @@ static void mcb_view_show_full_screen(GtkCheckMenuItem *, GMenuBar *);
GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
{
GtkWidget *result; /* Support à retourner */
- GtkWidget *menubar; /* Support pour éléments */
+ GtkWidget *menubar; /* Support pour éléments #1 */
GtkWidget *submenuitem; /* Sous-élément de menu */
+ GtkWidget *deepmenubar; /* Support pour éléments #2 */
GSList *rgroup; /* Groupe des boutons radio */
result = gtk_menu_item_new_with_mnemonic(_("_View"));
@@ -73,6 +81,20 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
menubar = gtk_menu_new();
gtk_menu_item_set_submenu(GTK_MENU_ITEM(result), menubar);
+ /* Affichage -> Panneaux latéraux */
+
+ submenuitem = qck_create_menu_item(NULL, NULL, _("Side panels"), NULL, NULL);
+ g_signal_connect(submenuitem, "select", G_CALLBACK(mcb_view_update_side_panels_list), bar);
+ gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+ deepmenubar = gtk_menu_new();
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), deepmenubar);
+
+ /* - */
+
+ submenuitem = qck_create_menu_separator();
+ gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
submenuitem = qck_create_radio_menu_item(ref, "textview", NULL, _("Text view"),
G_CALLBACK(mcb_view_change_support), bar);
add_accelerator_to_menu_item(submenuitem, "F2", accgroup);
@@ -113,6 +135,8 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
g_object_set_data(G_OBJECT(submenuitem), "kind_of_col", GUINT_TO_POINTER(BLC_BINARY));
gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+ /* - */
+
submenuitem = qck_create_menu_separator();
gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
@@ -194,6 +218,148 @@ void update_menu_view_for_view(GtkWidget *widget, GtkViewPanel *view, GMenuBar *
/******************************************************************************
* *
+* Paramètres : menuitem = élément de menu sélectionné. *
+* bar = barre de menu parente. *
+* *
+* Description : Réagit avec le menu "Affichage -> Panneaux latéraux". *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar)
+{
+ GtkWidget *menubar; /* Support pour éléments */
+ GtkAccelGroup *accgroup; /* Groupe de raccourcis */
+
+ typedef struct _panels_loading_filter
+ {
+ GtkContainer *support; /* Support pour éléments */
+ GtkAccelGroup *accel; /* Groupe de raccourcis */
+
+ PanelItemPersonality personality; /* Nature des éléments attendus*/
+ bool first; /* Premier ajout ? */
+
+ } panels_loading_filter;
+
+ panels_loading_filter pfilter;
+
+
+ menubar = gtk_menu_item_get_submenu(menuitem);
+
+ /* Réinitialisation */
+
+ void remove_panel_menu_item(GtkWidget *widget, GtkContainer *container)
+ {
+ gtk_container_remove(container, widget);
+
+ }
+
+ gtk_container_foreach(GTK_CONTAINER(menubar), (GtkCallback)remove_panel_menu_item, menubar);
+
+ /* Ajout des panneaux uniques */
+
+ bool add_side_panel_to_list(GPanelItem *panel, panels_loading_filter *filter)
+ {
+ const char *name; /* Désignation de l'entrée */
+ GtkWidget *submenuitem; /* Sous-élément de menu */
+ const char *bindings; /* Raccourcis clavier bruts */
+
+ if (gtk_panel_item_get_personality(panel) != filter->personality)
+ goto aptl_exit;
+
+ /* Séparation */
+
+ if (filter->first)
+ {
+ filter->first = false;
+
+ submenuitem = qck_create_menu_separator();
+ gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+ }
+
+ /* Elément de menu */
+
+ name = g_editor_item_get_name(G_EDITOR_ITEM(panel));
+
+ submenuitem = qck_create_check_menu_item(NULL, NULL, name,
+ G_CALLBACK(mcb_view_change_panel_docking), panel);
+
+ bindings = gtk_panel_item_get_key_bindings(panel);
+
+ if (bindings != NULL)
+ add_accelerator_to_menu_item(submenuitem, bindings, filter->accel);
+
+ gtk_container_add(filter->support, submenuitem);
+
+ /* Statut de la coche */
+
+ if (g_panel_item_is_docked(panel))
+ {
+ g_signal_handlers_disconnect_by_func(submenuitem, G_CALLBACK(mcb_view_change_panel_docking), panel);
+
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), TRUE);
+
+ g_signal_connect(submenuitem, "toggled", G_CALLBACK(mcb_view_change_panel_docking), panel);
+
+ }
+
+ aptl_exit:
+
+ return true;
+
+ }
+
+ accgroup = GTK_ACCEL_GROUP(g_object_get_data(G_OBJECT(bar), "accgroup"));
+
+ pfilter.support = GTK_CONTAINER(menubar);
+ pfilter.accel = accgroup;
+
+ pfilter.personality = PIP_SINGLETON;
+ pfilter.first = false;
+
+ browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter);
+
+ pfilter.personality = PIP_OTHER;
+ pfilter.first = true;
+
+ browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : menuitem = élément de menu ayant basculé. *
+* bar = barre de menu parente. *
+* *
+* Description : Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void mcb_view_change_panel_docking(GtkCheckMenuItem *menuitem, GPanelItem *item)
+{
+ gboolean active; /* Etat de sélection du menu */
+
+ active = gtk_check_menu_item_get_active(menuitem);
+
+ if (active)
+ g_panel_item_dock(item);
+ else
+ g_panel_item_undock(item);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : menuitem = élément de menu ayant basculé. *
* bar = barre de menu parente. *
* *
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
index e06b891..9eaa1df 100644
--- a/src/gui/panels/bookmarks.c
+++ b/src/gui/panels/bookmarks.c
@@ -236,6 +236,7 @@ static void g_bookmarks_panel_class_init(GBookmarksPanelClass *klass)
static void g_bookmarks_panel_init(GBookmarksPanel *panel)
{
GEditorItem *base; /* Version basique d'instance */
+ GPanelItem *pitem; /* Version parente du panneau */
GObject *ref; /* Espace de référencement */
GtkTreeStore *store; /* Modèle de gestion */
GtkWidget *treeview; /* Affichage de la liste */
@@ -255,6 +256,10 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel)
ref = G_OBJECT(base->widget);
g_object_set_data(ref, "panel", panel);
+ pitem = G_PANEL_ITEM(panel);
+
+ pitem->personality = PIP_SINGLETON;
+
/* Partie signets */
store = gtk_tree_store_new(BMC_COUNT, G_TYPE_OBJECT,
diff --git a/src/gui/panels/glance.c b/src/gui/panels/glance.c
index 306281a..6373edd 100644
--- a/src/gui/panels/glance.c
+++ b/src/gui/panels/glance.c
@@ -173,16 +173,24 @@ static void g_glance_panel_class_init(GGlancePanelClass *klass)
static void g_glance_panel_init(GGlancePanel *panel)
{
GEditorItem *base; /* Version basique d'instance */
+ GPanelItem *pitem; /* Version parente du panneau */
GtkWidget *area; /* Surface de dessin réelle */
base = G_EDITOR_ITEM(panel);
base->name = _("Glance");
+ base->widget = gtk_event_box_new();
+
+ pitem = G_PANEL_ITEM(panel);
+
+ pitem->personality = PIP_SINGLETON;
+
+ /* Support de dessin */
+
area = gtk_drawing_area_new();
gtk_widget_show(area);
- base->widget = gtk_event_box_new();
gtk_container_add(GTK_CONTAINER(base->widget), area);
gtk_widget_show(base->widget);
diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c
index 74945c7..4d4be0c 100644
--- a/src/gui/panels/history.c
+++ b/src/gui/panels/history.c
@@ -156,6 +156,7 @@ static void g_history_panel_class_init(GHistoryPanelClass *klass)
static void g_history_panel_init(GHistoryPanel *panel)
{
GEditorItem *base; /* Version basique d'instance */
+ GPanelItem *pitem; /* Version parente du panneau */
GObject *ref; /* Espace de référencement */
GtkWidget *scrollwnd; /* Support défilant */
GtkWidget *treeview; /* Affichage de la liste */
@@ -173,6 +174,10 @@ static void g_history_panel_init(GHistoryPanel *panel)
ref = G_OBJECT(panel);
+ pitem = G_PANEL_ITEM(panel);
+
+ pitem->personality = PIP_SINGLETON;
+
/* Liste des éléments d'évolution */
scrollwnd = gtk_scrolled_window_new(NULL, NULL);
@@ -305,7 +310,7 @@ GEditorItem *g_history_panel_new(GObject *ref)
result = g_object_new(G_TYPE_HISTORY_PANEL, NULL);
g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_HISTORY_ID,
- _("Change history"), G_EDITOR_ITEM(result)->widget, "eM");
+ _("Change history"), G_EDITOR_ITEM(result)->widget, "eN");
return result;
diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c
index ab815e4..7893666 100644
--- a/src/gui/panels/log.c
+++ b/src/gui/panels/log.c
@@ -120,12 +120,18 @@ G_DEFINE_TYPE(GLogPanel, g_log_panel, G_TYPE_PANEL_ITEM);
static void g_log_panel_class_init(GLogPanelClass *klass)
{
GObjectClass *object; /* Autre version de la classe */
+ GPanelItemClass *panel; /* Version parente de la classe*/
object = G_OBJECT_CLASS(klass);
object->dispose = (GObjectFinalizeFunc/* ! */)g_log_panel_dispose;
object->finalize = (GObjectFinalizeFunc)g_log_panel_finalize;
+ panel = G_PANEL_ITEM_CLASS(klass);
+
+ panel->unique = true;
+ panel->bindings = "<Shift>F1";
+
}
@@ -143,16 +149,27 @@ static void g_log_panel_class_init(GLogPanelClass *klass)
static void g_log_panel_init(GLogPanel *panel)
{
+ GEditorItem *base; /* Version basique d'instance */
+ GPanelItem *pitem; /* Version parente du panneau */
GtkWidget *scrolled; /* Fenêtre avec défilements */
GtkTreeStore *store; /* Modèle de gestion */
GtkWidget *treeview; /* Affichage de la liste */
GtkCellRenderer *renderer; /* Moteur de rendu de colonne */
GtkTreeViewColumn *column; /* Colonne de la liste */
- GEditorItem *base; /* Version basique d'instance */
+
+ base = G_EDITOR_ITEM(panel);
scrolled = gtk_scrolled_window_new(NULL, NULL);
gtk_widget_show(scrolled);
+ base->widget = scrolled;
+
+ pitem = G_PANEL_ITEM(panel);
+
+ pitem->personality = PIP_SINGLETON;
+
+ /* Construction graphique */
+
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
@@ -184,9 +201,6 @@ static void g_log_panel_init(GLogPanel *panel)
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
- base = G_EDITOR_ITEM(panel);
- base->widget = scrolled;
-
}
diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h
index b3a9f10..e902722 100644
--- a/src/gui/panels/panel-int.h
+++ b/src/gui/panels/panel-int.h
@@ -29,8 +29,7 @@
#include "panel.h"
-#include <gtk/gtkbin.h>
-#include <gtk/gtkwidget.h>
+#include <gtk/gtk.h>
#include "../editem-int.h"
@@ -45,10 +44,14 @@ struct _GPanelItem
DL_LIST_ITEM(link); /* Maillon de liste chaînée */
+ PanelItemPersonality personality; /* Nature de l'élément */
+
const char *lname; /* Description longue */
const char *path; /* Chemin vers la place idéale */
+ bool docked; /* Panneau inscrusté ? */
+
};
@@ -57,18 +60,25 @@ typedef struct _panel_node
{
struct _panel_node *parent; /* Noeud parent */
- char *path; /* Chemin du nom courant */
- size_t depth; /* Profondeur utilisée */
+ union
+ {
+ GtkWidget *widget; /* Accès généraliste */
+ GtkWidget *station; /* Station d'accueil simple */
+ GtkWidget *paned; /* Station d'accueil composée */
- bool simple; /* Noeud sans division */
+ };
union
{
- GtkWidget *station; /* Station d'accueil simple */
+ /* Version simple */
+ struct
+ {
+ char *path; /* Chemin du nom courant */
+ };
+ /* Version composée */
struct
{
- GtkWidget *paned; /* Station d'accueil composée */
struct _panel_node *first; /* Premier sous élément */
struct _panel_node *second; /* Second sous élément */
};
@@ -78,7 +88,16 @@ typedef struct _panel_node
} panel_node;
-#define GET_PANEL_NODE_WIDGET(node) (node->simple ? node->station : node->paned)
+
+#define IS_SIMPLE_NODE(nd) \
+ ({ \
+ bool __result; \
+ __result = GTK_IS_DOCK_STATION(nd->station); \
+ assert(__result || GTK_IS_PANED(nd->paned)); \
+ __result; \
+ })
+
+
/* Elément réactif pour panneaux de l'éditeur (classe) */
@@ -86,6 +105,9 @@ struct _GPanelItemClass
{
GEditorItemClass parent; /* A laisser en premier */
+ bool unique; /* Panneau instanciable ? */
+ const char *bindings; /* Raccourci clavier éventuel */
+
GtkBin *first; /* Elément racine */
};
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index 01307cb..8af8672 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -25,6 +25,7 @@
#include "panel.h"
+#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <sys/param.h>
@@ -38,6 +39,7 @@
#include "regedit.h"
#include "strings.h"
#include "symbols.h"
+#include "../../common/extstr.h"
#include "../../gtkext/easygtk.h"
#include "../../gtkext/gtkdockable-int.h"
#include "../../gtkext/gtkdockstation.h"
@@ -80,7 +82,7 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *);
/* Crée un nouveau noeud pour un panneau particulier. */
-static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t);
+//static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t);
/* Prépare une nouvelle sous-division pour deux panneaux. */
static void switch_panel_node_into_paned(panel_node *, bool, bool);
@@ -88,41 +90,34 @@ static void switch_panel_node_into_paned(panel_node *, bool, bool);
/* Met en place un nouveau noeud dans une division. */
static void attach_panel_node_to_paned(panel_node *, panel_node *, bool);
-/* Valorise la correspondance entre un noeud et un chemin. */
-static int compute_panel_node_matching_score(const panel_node *, const char *);
-/* Calcule la longueur du plus court chemin vers un 'M'. */
-static size_t _compute_panel_node_main_level(const panel_node *);
-/* Recherche le noeud constituant la branche principale. */
-static panel_node *find_main_panel_node_branch(panel_node *, panel_node *);
-/* Place au bon endroit un panneau donné. */
-static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t);
+/* Crée un nouveau noeud pour un panneau particulier. */
+static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *);
-/* Met à jour l'affichage suite à un changement hiérarchique. */
-static void rebuild_panels_interface(const panel_node *);
-/* ---------------------- REAJUSTEMENT AUTOMATIQUE DE L'ESPACE ---------------------- */
+/* Obtient la désignation d'un élément hiérarchie des noeuds. */
+static char *get_panel_node_path(const panel_node *);
+/* Détermine la plus grande longueur commune entre éléments. */
+static size_t compute_path_common_length(const panel_node *, const char *);
-/* Part réservée aux parties principales (en %) */
-#define MAIN_PART_PERCENT 70
+/* Détermine la plus grande profondeur d'un noeud de panneaux. */
+static unsigned int compute_deepest_depth(const panel_node *);
-/* Part minimale des petits composants (en %) */
-#define MIN_PART_PERCENT 20
+/* Place au bon endroit un panneau donné. */
+static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t);
+/* Tente de mettre la main sur une station d'accueil. */
+static panel_node *find_node_for_station(panel_node *, GtkWidget *);
-/* Met à jour l'affichage suite à un changement hiérarchique. */
-static void auto_resize_panels(GtkWidget *, GdkRectangle *, gpointer);
+/* Efface de l'organisation un noeud donné en place. */
+static void delete_panel_node(panel_node *);
-/* S'enquiert de la taille idéale pour un noeud. */
-static void get_panel_node_size_request(const panel_node *, GtkRequisition *);
-/* Impose une taille accordée à un noeud. */
-static void set_panel_node_size_request(const panel_node *, const GtkRequisition *);
@@ -167,6 +162,8 @@ static void g_panel_item_init(GPanelItem *item)
{
DL_LIST_ITEM_INIT(&item->link);
+ item->personality = PIP_INVALID;
+
}
@@ -239,7 +236,8 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con
/******************************************************************************
* *
-* Paramètres : ref = espace de référencement global. *
+* Paramètres : personality = nature du panneau à mettre en place. *
+* ref = espace de référencement global. *
* name = nom associé à l'élément. *
* lname = description longue du panneau. *
* widget = composant à présenter à l'affichage. *
@@ -253,12 +251,15 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con
* *
******************************************************************************/
-GEditorItem *g_panel_item_new(GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path)
+GEditorItem *g_panel_item_new(PanelItemPersonality personality, GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path)
{
GPanelItem *result; /* Structure à retourner */
result = g_object_new(G_TYPE_PANEL_ITEM, NULL);
+ assert(personality > PIP_INVALID && personality < PIP_COUNT);
+ result->personality = personality;
+
g_panel_item_init_ext(result, ref, name, lname, widget, path);
return G_EDITOR_ITEM(result);
@@ -325,6 +326,44 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item)
/******************************************************************************
* *
+* Paramètres : item = instance GTK à consulter. *
+* *
+* Description : Fournit une indication sur la personnalité du panneau. *
+* *
+* Retour : Identifiant lié à la nature du panneau. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PanelItemPersonality gtk_panel_item_get_personality(const GPanelItem *item)
+{
+ return item->personality;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = instance GTK dont l'interface est à consulter. *
+* *
+* Description : Indique la définition d'un éventuel raccourci clavier. *
+* *
+* Retour : Description d'un raccourci ou NULL si aucun de défini. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *gtk_panel_item_get_key_bindings(const GPanelItem *item)
+{
+ return G_PANEL_ITEM_GET_CLASS(item)->bindings;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : name = désignation courte servant de clef. *
* *
* Description : Recherche un panneau à partir de son nom court. *
@@ -364,16 +403,95 @@ GPanelItem *g_panel_item_get(const char *name)
* *
******************************************************************************/
+static void dump_tree(GtkWidget *root, unsigned int level)
+{
+ unsigned int i;
+ GList *list;
+ GList *iter;
+
+ if (strcmp(G_OBJECT_TYPE_NAME(G_OBJECT(root)), "GtkButton") == 0)
+ return;
+
+ for (i = 0; i < level; i++)
+ fprintf(stderr, " ");
+
+ fprintf(stderr, "%s (%p)\n", G_OBJECT_TYPE_NAME(G_OBJECT(root)), root);
+
+ if (GTK_IS_CONTAINER(root))
+ {
+ list = gtk_container_get_children(GTK_CONTAINER(root));
+
+ for (iter = list; iter != NULL; iter = g_list_next(iter))
+ dump_tree(GTK_WIDGET(iter->data), level + 1);
+
+ }
+
+}
+
+
+void dump_node(panel_node *node, unsigned int level)
+{
+ unsigned i;
+
+ for (i = 0; i < level; i++)
+ fprintf(stderr, " ");
+
+ fprintf(stderr, "%p %p -- widget %p -- '%s'\n", node->parent, node, node->station,
+ IS_SIMPLE_NODE(node) ? node->path : "-");
+
+ if (!IS_SIMPLE_NODE(node))
+ {
+ dump_node(node->first, level + 1);
+ dump_node(node->second, level + 1);
+ }
+
+
+}
+
+
+
void g_panel_item_dock(GPanelItem *item)
{
+ assert(!item->docked);
+
+ fprintf(stderr, "\n---------\n\n");
+
/* Tout est à faire... */
if (_nodes == NULL)
{
- _nodes = create_simple_panel_node_for_item(item, item->path, 0);
- gtk_container_add(GTK_CONTAINER(_support), _nodes->station);
+ _nodes = create_simple_panel_node_for_item(item, item->path);
+ gtk_container_add(GTK_CONTAINER(_support), _nodes->widget);
}
else insert_item_as_panel_node(item, _nodes, item->path, 0);
+ item->docked = true;
+
+
+
+ dump_tree(_support, 0);
+ fprintf(stderr, "\n");
+ dump_node(_nodes, 0);
+
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : item = composant d'affichage à consulter. *
+* *
+* Description : Indique si le composant repose sur un support de l'éditeur. *
+* *
+* Retour : true si le composant est bien incrusté quelque part. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_panel_item_is_docked(const GPanelItem *item)
+{
+ return item->docked;
+
}
@@ -391,12 +509,25 @@ void g_panel_item_dock(GPanelItem *item)
void g_panel_item_undock(GPanelItem *item)
{
- GtkWidget *station; /* Base du remplacement */
+ GtkWidget *station; /* Support courant */
+ panel_node *node; /* Noeud à supprimer */
- station = gtk_widget_get_parent(G_EDITOR_ITEM(item)->widget); /* NoteBook */
- station = gtk_widget_get_parent(station); /* DockStation */
+ assert(item->docked);
- gtk_dock_panel_remove_widget(GTK_DOCK_STATION(station), G_EDITOR_ITEM(item)->widget);
+ gtk_dockable_decompose(GTK_DOCKABLE(item), &station);
+
+ gtk_dock_station_remove_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
+
+ if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(station)) == 0)
+ {
+ node = find_node_for_station(_nodes, station);
+ assert(node != NULL);
+
+ delete_panel_node(node);
+
+ }
+
+ item->docked = false;
}
@@ -427,7 +558,7 @@ GtkWidget *init_panels2(GCallback handler, gpointer data)
result = gtk_event_box_new();
gtk_widget_show(result);
- g_signal_connect(result, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);
+ //g_signal_connect(result, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);
_support = result;
_handler = handler;
@@ -454,10 +585,10 @@ void load_main_panels(GObject *ref)
{
GPanelItem *item; /* Panneau de base à charger */
- item = create_regedit_panel(ref);
+ item = create_log_panel(ref);
g_panel_item_dock(item);
- item = create_log_panel(ref);
+ item = create_regedit_panel(ref);
g_panel_item_dock(item);
item = create_symbols_panel(ref);
@@ -478,54 +609,49 @@ void load_main_panels(GObject *ref)
}
-
-/* ---------------------------------------------------------------------------------- */
-/* MECANISMES DE PLACEMENT DES PANNEAUX */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : item = composant à présenter à l'affichage. *
-* path = partie du chemin représentée ici. *
-* depth = profondeur du chemin utilisé. *
+* Paramètres : handle = routine à appeler pour chaque panneau. *
+* data = données fournies pour accompagner cet appel. *
* *
-* Description : Crée un nouveau noeud pour un panneau particulier. *
+* Description : Effectue le parcours de tous les panneaux chargés. *
* *
-* Retour : Structure d'accueil mise en place. *
+* Retour : true si le parcours a été total, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path, size_t depth)
+bool browse_all_item_panels(handle_panel_item_fc handle, void *data)
{
- panel_node *result; /* Structure à retourner */
- GtkWidget *station; /* Premier support concentré */
-
- result = (panel_node *)calloc(1, sizeof(panel_node));
-
- result->path = strdup(path);
- result->depth = depth;
+ bool result; /* Résultat à renvoyer */
+ GPanelItem *iter; /* Boucle de parcours */
- result->simple = true;
+ result = true;
- station = gtk_dock_station_new();
- g_signal_connect(station, "switch-widget", _handler, _data);
- gtk_widget_show(station);
+ panels_list_for_each(iter, _panels_list)
+ {
+ result = handle(iter, data);
- result->station = station;
+ if (!result) break;
- gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
+ }
return result;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* MECANISMES DE PLACEMENT DES PANNEAUX */
+/* ---------------------------------------------------------------------------------- */
+
+
+
/******************************************************************************
* *
-* Paramètres : item = composant à présenter à l'affichage. *
+* Paramètres : node = noeud à diviser. *
* horiz = indique le type d'orientation désiré. *
* first = indication sur l'emplacement à utiliser. *
* *
@@ -537,51 +663,98 @@ static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const cha
* *
******************************************************************************/
-static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool first)
+static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool first)
{
- panel_node *moved; /* Noeud descendu d'un étage */
GtkWidget *widget; /* Composant à traiter */
+ panel_node *parent; /* Lien de parenté à conserver */
+ panel_node *moved; /* Noeud descendu d'un étage */
+
+ /* Décroche graphiquement le support */
+
+ widget = node->widget;
+
+ g_object_ref(G_OBJECT(widget));
+ gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
/* Descend l'élément actuel */
+ parent = node->parent;
+
moved = (panel_node *)calloc(1, sizeof(panel_node));
- memcpy(moved, current, sizeof(panel_node));
- moved->parent = current;
+ memcpy(moved, node, sizeof(panel_node));
- widget = GET_PANEL_NODE_WIDGET(current);
+ if (!IS_SIMPLE_NODE(moved))
+ {
+ moved->first->parent = moved;
+ moved->second->parent = moved;
+ }
- g_object_ref(G_OBJECT(widget));
- gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
+ /* Création du nouveau niveau intermédiaire */
- if (first)
- current->first = moved;
+ if (horiz)
+ node->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
else
- current->second = moved;
+ node->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
- /* Achève la transformation */
+ gtk_widget_show(node->paned);
- current->path = NULL;
+ if (parent == NULL)
+ attach_panel_node_to_paned(parent, node, true);
+ else
+ attach_panel_node_to_paned(parent, node, parent->first == node);
- current->simple = false;
- current->station = NULL;
- if (horiz)
- current->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
- else
- current->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
- gtk_widget_show(current->paned);
+ /* Premier ajustement */
- /* Replace le composant d'origine */
+ void split_paned_support(GtkWidget *support, GdkRectangle *alloc, gpointer data)
+ {
+ GtkOrientation orientation;
+ gint position;
- if (first)
- gtk_paned_add1(GTK_PANED(current->paned), widget);
- else
- gtk_paned_add2(GTK_PANED(current->paned), widget);
+ orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(support));
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ position = alloc->width / 2;
+ else
+ position = alloc->height / 2;
+
+ /*
+ if (position < 50)
+ position *= 2;
+ */
+
+ gtk_paned_set_position(GTK_PANED(support), position);
+
+ fprintf(stderr, "widget size is currently %dx%d\n", alloc->width, alloc->height);
+
+
+ fprintf(stderr, "position = %d\n", position);
+
+ fprintf(stderr, "---\n");
+
+
+ g_signal_handlers_disconnect_by_func(support, G_CALLBACK(split_paned_support), NULL);
+
+ }
+
+ //g_signal_connect(current->paned, "size-allocate", G_CALLBACK(split_paned_support), NULL);
+
+ static int __counter = 0;
+
+
+
+ if (++__counter == 4)
+ gtk_paned_set_position(GTK_PANED(node->paned), 100);
+
+
+
+
+ /* Replace le composant d'origine */
- g_object_unref(G_OBJECT(widget));
+ attach_panel_node_to_paned(node, moved, first);
}
@@ -602,67 +775,143 @@ static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool f
static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, bool first)
{
- GtkWidget *widget; /* Composant à traiter */
+ node->parent = parent;
+
+ /* On se trouve à la racine... */
- /* Raccordement hiérarchique */
+ if (parent == NULL)
+ gtk_container_add(GTK_CONTAINER(_support), node->widget);
- if (first)
- parent->first = node;
else
- parent->second = node;
+ {
+ /* Raccordement hiérarchique */
- node->parent = parent;
+ if (first)
+ parent->first = node;
+ else
+ parent->second = node;
- /* Raccordement graphique */
+ /* Raccordement graphique */
- widget = GET_PANEL_NODE_WIDGET(node);
+ assert(!IS_SIMPLE_NODE(parent));
- if (first)
- gtk_paned_add1(GTK_PANED(parent->paned), widget);
- else
- gtk_paned_add2(GTK_PANED(parent->paned), widget);
+ if (first)
+ gtk_paned_pack1(GTK_PANED(parent->paned), node->widget, TRUE, FALSE);
+ else
+ gtk_paned_pack2(GTK_PANED(parent->paned), node->widget, TRUE, FALSE);
+
+ }
}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+
+
+
+
/******************************************************************************
* *
-* Paramètres : node = noeud d'où lancer les recherches. *
-* target = identifiant de la position visée. *
+* Paramètres : item = composant à présenter à l'affichage. *
+* path = partie du chemin représentée ici. *
* *
-* Description : Valorise la correspondance entre un noeud et un chemin. *
+* Description : Crée un nouveau noeud pour un panneau particulier. *
* *
-* Retour : Bilan de l'évaluation. *
+* Retour : Structure d'accueil mise en place. *
* *
* Remarques : - *
* *
******************************************************************************/
-static int compute_panel_node_matching_score(const panel_node *node, const char *target)
+static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path)
{
- int result; /* Bilan à retourner */
- size_t len; /* Longueur de comparaison */
- size_t i; /* Boucle de parcours */
+ panel_node *result; /* Structure à retourner */
+ GtkWidget *station; /* Premier support concentré */
- if (node->simple)
- {
- result = 0;
+ /* Partie graphique */
- len = strlen(node->path);
- len = MIN(len, strlen(target));
+ station = gtk_dock_station_new();
+ g_signal_connect(station, "switch-widget", _handler, _data);
+ gtk_widget_show(station);
- for (i = 0; i < len; i++)
- {
- if (node->path[i] != target[i]) break;
- else result++;
- }
+ gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
- }
+ /* Partie invisible */
+
+ result = (panel_node *)calloc(1, sizeof(panel_node));
+
+ result->station = station;
+
+ result->path = strdup(path);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : node = noeud dont la désignation est à obtenir. *
+* *
+* Description : Obtient la désignation d'un élément hiérarchie des noeuds. *
+* *
+* Retour : Chaîne construite à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *get_panel_node_path(const panel_node *node)
+{
+ char *result; /* Valeur à retourner */
+ char *extra; /* Complément à ajouter */
+
+ if (IS_SIMPLE_NODE(node))
+ result = strdup(node->path);
else
{
- result = compute_panel_node_matching_score(node->first, target);
- result = MAX(result, compute_panel_node_matching_score(node->second, target));
+ result = get_panel_node_path(node->first);
+
+ extra = get_panel_node_path(node->second);
+ result = stradd(result, "-");
+ result = stradd(result, extra);
+ free(extra);
+
+ result = strprep(result, "(");
+ result = stradd(result, ")");
+
+
}
return result;
@@ -673,8 +922,9 @@ static int compute_panel_node_matching_score(const panel_node *node, const char
/******************************************************************************
* *
* Paramètres : node = noeud d'où lancer les recherches. *
+* target = identifiant de la position visée. *
* *
-* Description : Calcule la longueur du plus court chemin vers un 'M'. *
+* Description : Détermine la plus grande longueur commune entre éléments. *
* *
* Retour : Bilan de l'évaluation. *
* *
@@ -682,23 +932,34 @@ static int compute_panel_node_matching_score(const panel_node *node, const char
* *
******************************************************************************/
-static size_t _compute_panel_node_main_level(const panel_node *node)
+static size_t compute_path_common_length(const panel_node *node, const char *target)
{
- size_t result; /* Plus petit chemin à renvoyer*/
+ size_t result; /* Taille à retourner */
+ size_t len; /* Longueur de comparaison */
+ size_t common1; /* Tron common avec le côté #1 */
+ size_t common2; /* Tron common avec le côté #2 */
- if (node->simple)
+ if (IS_SIMPLE_NODE(node))
{
- result = strcspn(&node->path[node->depth], "M");
+ len = MIN(strlen(node->path), strlen(target));
- if (node->path[node->depth + result] == '\0')
- result = SIZE_MAX;
+ /**
+ * Il n'y a pas forcément de base commune entre deux branches,
+ * donc on parcourt les chemins depuis leur base respective.
+ */
+ for (result = 0; result < len; result++)
+ if (node->path[result] != target[result])
+ break;
}
else
{
- result = _compute_panel_node_main_level(node->first);
- result = MIN(result, _compute_panel_node_main_level(node->second));
+ common1 = compute_path_common_length(node->first, target);
+ common2 = compute_path_common_length(node->second, target);
+
+ result = MAX(common1, common2);
+
}
return result;
@@ -708,31 +969,33 @@ static size_t _compute_panel_node_main_level(const panel_node *node)
/******************************************************************************
* *
-* Paramètres : a = première branche à analyser. *
-* b = seconde branche à analyser. *
+* Paramètres : node = noeud d'où lancer les mesures. *
* *
-* Description : Recherche le noeud constituant la branche principale. *
+* Description : Détermine la plus grande profondeur d'un noeud de panneaux. *
* *
-* Retour : Branche principale ou NULL si aucune n'est idéale. *
+* Retour : Valeur strictement positive. *
* *
* Remarques : - *
* *
******************************************************************************/
-static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
+static unsigned int compute_deepest_depth(const panel_node *node)
{
- panel_node *result; /* Trouvaille à remonter */
- size_t main_a; /* Proximité du 'M' côté a */
- size_t main_b; /* Proximité du 'M' côté b */
-
- main_a = _compute_panel_node_main_level(a);
- main_b = _compute_panel_node_main_level(b);
+ unsigned int result; /* Profondeur à renvoyer */
+ unsigned int depth1; /* Profondeur du côté #1 */
+ unsigned int depth2; /* Profondeur du côté #2 */
- if (main_a == SIZE_MAX && main_b == SIZE_MAX)
- result = NULL;
+ if (IS_SIMPLE_NODE(node))
+ result = 1;
else
- result = (main_a < main_b ? a : b);
+ {
+ depth1 = compute_deepest_depth(node->first);
+ depth2 = compute_deepest_depth(node->second);
+
+ result = MAX(depth1, depth2);
+
+ }
return result;
@@ -741,10 +1004,10 @@ static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
/******************************************************************************
* *
-* Paramètres : item = composant à présenter à l'affichage. *
-* node = point d'insertion courant. *
-* path = partie du chemin représentée ici. *
-* depth = profondeur du chemin utilisé. *
+* Paramètres : item = composant à présenter à l'affichage. *
+* node = point d'insertion courant. *
+* path = partie du chemin représentée ici. *
+* consumed = profondeur du chemin utilisé. *
* *
* Description : Place au bon endroit un panneau donné. *
* *
@@ -754,58 +1017,47 @@ static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
* *
******************************************************************************/
-static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t depth)
+static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t consumed)
{
char div; /* Division demandée */
bool horiz; /* Traduction en composant */
bool first; /* Point d'insertion */
panel_node *new; /* Nouveau noeud créé */
- int score1; /* Score de la 1ère branche */
- int score2; /* Score de la 2nde branche */
- panel_node *support; /* Noeud d'accueil désigné */
+ size_t common1; /* Tron common avec le côté #1 */
+ size_t common2; /* Tron common avec le côté #2 */
- if (node->simple)
- {
- /* Si on est sur la bonne voie... */
- if (compute_panel_node_matching_score(node, path) > 0)
- {
- /* Le parcours s'arrête ici ! */
- if (strcmp(node->path, path) == 0)
- gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item));
- /* On ne peut aller plus loin, on doit diviser... */
- else
- {
- div = toupper(path[depth]);
- first = (div == 'E' || div == 'S');
- horiz = (div == 'W' || div == 'E');
-
- switch_panel_node_into_paned(node, horiz, first);
-
- new = create_simple_panel_node_for_item(item, path, depth);
+ fprintf(stderr, "=== INSERTING '%s' (%zu)... -> '%s'\n", path, consumed,
+ IS_SIMPLE_NODE(node) ? node->path : "-");
- attach_panel_node_to_paned(node, new, !first);
- rebuild_panels_interface(node);
- }
-
- }
+ if (IS_SIMPLE_NODE(node))
+ {
+ /* Le parcours s'arrête ici ! */
+ if (strcmp(node->path, path) == 0)
+ gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item));
/* On ne peut aller plus loin, on doit diviser... */
else
{
- div = toupper(path[depth]);
- first = (div == 'E' || div == 'S');
+ div = toupper(path[consumed]);
+ first = (div == 'W' || div == 'N');
horiz = (div == 'W' || div == 'E');
- switch_panel_node_into_paned(node, horiz, first);
+ fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz);
- new = create_simple_panel_node_for_item(item, path, depth);
+ fprintf(stderr, "--- cutting %p\n", node->station);
- attach_panel_node_to_paned(node, new, !first);
+ switch_panel_node_into_paned(node, horiz, !first);
- rebuild_panels_interface(node);
+ new = create_simple_panel_node_for_item(item, path);
+
+ attach_panel_node_to_paned(node, new, first);
+
+
+ fprintf(stderr, "1# [%p] widget = %p --- split :: %p // %p\n",
+ node, node->station, node->first, node->second);
}
@@ -815,62 +1067,44 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
else
{
- score1 = compute_panel_node_matching_score(node->first, path);
- score2 = compute_panel_node_matching_score(node->second, path);
+ common1 = compute_path_common_length(node->first, path);
+ common2 = compute_path_common_length(node->second, path);
+
+
+ fprintf(stderr, " - L1 :: %zu <-> '%s'\n", common1, get_panel_node_path(node->first));
+ fprintf(stderr, " - L2 :: %zu <-> '%s'\n", common2, get_panel_node_path(node->second));
+
/* Si une descente est possible... */
- if (score1 > 0 || score2 > 0)
+ if (common1 > 0 || common2 > 0)
{
- if (node->first->simple || node->second->simple)
- depth++;
-
- if (score1 > score2)
- insert_item_as_panel_node(item, node->first, path, depth);
+ if (common1 > common2)
+ insert_item_as_panel_node(item, node->first, path, common1);
else
- insert_item_as_panel_node(item, node->second, path, depth);
+ insert_item_as_panel_node(item, node->second, path, common2);
}
/* Sinon, on doit diviser qqch... */
else
{
- /* Si l'élément doit passer en force */
- if (isupper(path[depth]))
- {
- div = path[depth];
- first = (div == 'E' || div == 'S');
- horiz = (div == 'W' || div == 'E');
-
- switch_panel_node_into_paned(node, horiz, first);
-
- new = create_simple_panel_node_for_item(item, path, depth);
-
- attach_panel_node_to_paned(node, new, !first);
-
- rebuild_panels_interface(node);
-
- }
-
- else
- {
- support = find_main_panel_node_branch(node->first, node->second);
- if (support == NULL)
- support = node->first;
+ div = toupper(path[consumed]);
+ first = (div == 'W' || div == 'N');
+ horiz = (div == 'W' || div == 'E');
- div = toupper(path[depth]);
- first = (div == 'E' || div == 'S');
- horiz = (div == 'W' || div == 'E');
+ fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz);
- switch_panel_node_into_paned(support, horiz, first);
+ switch_panel_node_into_paned(node, horiz, !first);
- new = create_simple_panel_node_for_item(item, path, depth);
+ new = create_simple_panel_node_for_item(item, path);
- attach_panel_node_to_paned(support, new, !first);
+ attach_panel_node_to_paned(node, new, first);
- rebuild_panels_interface(support);
- }
+ fprintf(stderr, "2# [%p] split :: %p-%p // %p-%p\n", node,
+ node->first, node->first->widget,
+ node->second, node->second->widget);
}
@@ -881,55 +1115,42 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
/******************************************************************************
* *
-* Paramètres : current = point de départ de la réorganisation graphique. *
+* Paramètres : node = point de départ des recherches locales. *
* *
-* Description : Met à jour l'affichage suite à un changement hiérarchique. *
+* Description : Tente de mettre la main sur une station d'accueil. *
* *
-* Retour : - *
+* Retour : Eventuel noeud trouvé ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void rebuild_panels_interface(const panel_node *current)
+static panel_node *find_node_for_station(panel_node *node, GtkWidget *station)
{
- GtkWidget *widget; /* Composant à traiter */
- panel_node *parent; /* Raccourci confortable */
-
- widget = GET_PANEL_NODE_WIDGET(current);
+ panel_node *result; /* Bilan à remonter */
- /* On se trouve à la racine... */
- if (current->parent == NULL)
- gtk_container_add(GTK_CONTAINER(_support), widget);
+ if (IS_SIMPLE_NODE(node))
+ result = (node->station == station ? node : NULL);
- /* Sinon, une sous-division ne peut venir que d'une division... */
else
{
- /* BUG_ON(parent->simple) */
-
- parent = current->parent;
+ result = find_node_for_station(node->first, station);
- if (current == parent->first)
- gtk_paned_add1(GTK_PANED(parent->paned), widget);
- else
- gtk_paned_add2(GTK_PANED(parent->paned), widget);
+ if (result == NULL)
+ result = find_node_for_station(node->second, station);
}
-}
-
-
+ return result;
-/* ---------------------------------------------------------------------------------- */
-/* REAJUSTEMENT AUTOMATIQUE DE L'ESPACE */
-/* ---------------------------------------------------------------------------------- */
+}
/******************************************************************************
* *
-* Paramètres : current = point de départ de la réorganisation graphique. *
+* Paramètres : node = noeud à supprimer de l'arbre des noeuds. *
* *
-* Description : Met à jour l'affichage suite à un changement hiérarchique. *
+* Description : Efface de l'organisation un noeud donné en place. *
* *
* Retour : - *
* *
@@ -937,77 +1158,91 @@ static void rebuild_panels_interface(const panel_node *current)
* *
******************************************************************************/
-static void auto_resize_panels(GtkWidget *support, GdkRectangle *alloc, gpointer data)
+static void delete_panel_node(panel_node *node)
{
- GtkRequisition available; /* Taille disponible */
+ panel_node *parent; /* Noeud parent à transformer */
+ GtkWidget *widget; /* Composant à traiter */
+ panel_node *grandparent; /* Noeud supérieur au parent */
+ panel_node *remaining; /* Noeud restant */
- //g_signal_handlers_disconnect_by_func(support, G_CALLBACK(auto_resize_panels), NULL);
+ assert(IS_SIMPLE_NODE(node));
- available.width = alloc->width;
- available.height = alloc->height;
+ parent = node->parent;
- set_panel_node_size_request(_nodes, &available);
+ /* Destruction du noeud */
- //g_signal_connect(support, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);
+ widget = node->station;
+ gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
-}
+ free(node->path);
+ free(node);
-/******************************************************************************
-* *
-* Paramètres : node = noeud à consulter. *
-* req = taille demandée par le noeud. [OUT] *
-* *
-* Description : S'enquiert de la taille idéale pour un noeud. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ /* Suppression du niveau intermédiaire */
-static void get_panel_node_size_request(const panel_node *node, GtkRequisition *req)
-{
- gint handle_size; /* Taille de la séparation */
- GtkRequisition tmp; /* Stockage temporaire */
+ if (parent != NULL)
+ {
+ remaining = (node == parent->first ? parent->second : parent->first);
- if (node->simple)
- gtk_widget_get_preferred_size(node->station, NULL, req);
+ /* Décroche graphiquement le support */
- else
- {
- gtk_widget_style_get(node->paned, "handle-size", &handle_size, NULL);
+ widget = remaining->widget;
- if (HAS_H_ORIENTATION(node->paned))
- {
- req->width = handle_size;
- req->height = 0;
- }
- else
+ g_object_ref(G_OBJECT(widget));
+ gtk_container_remove(GTK_CONTAINER(parent->paned), widget);
+
+ /* Supprime le composant graphique intermédiaire */
+
+ gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(parent->paned)), parent->paned);
+
+ /* Réinsère la partie restante */
+
+ grandparent = parent->parent;
+
+ memcpy(parent, remaining, sizeof(panel_node));
+
+ if (!IS_SIMPLE_NODE(parent))
{
- req->width = 0;
- req->height = handle_size;
+ parent->first->parent = parent;
+ parent->second->parent = parent;
}
- get_panel_node_size_request(node->first, &tmp);
- req->width += tmp.width;
- req->height += tmp.height;
+ free(remaining);
- get_panel_node_size_request(node->second, &tmp);
- req->width += tmp.width;
- req->height += tmp.height;
+ if (grandparent == NULL)
+ attach_panel_node_to_paned(grandparent, parent, true);
+ else
+ attach_panel_node_to_paned(grandparent, parent, grandparent->first == parent);
}
}
+
+
+
+
+
+
+
+
+
+
+
+
+#if 1
+
+
+#include "../../core/params.h"
+
+
+
/******************************************************************************
* *
-* Paramètres : node = noeud à consulter. *
-* space = taille disponible pour le noeud. *
+* Paramètres : current = point de départ de la réorganisation graphique. *
* *
-* Description : Impose une taille accordée à un noeud. *
+* Description : Met à jour l'affichage suite à un changement hiérarchique. *
* *
* Retour : - *
* *
@@ -1015,125 +1250,45 @@ static void get_panel_node_size_request(const panel_node *node, GtkRequisition *
* *
******************************************************************************/
-static void set_panel_node_size_request(const panel_node *node, const GtkRequisition *space)
+void save_panel_nodes(void)
{
- GtkRequisition first_req; /* Taille demandée par n°1 */
- GtkRequisition second_req; /* Taille demandée par n°2 */
- gint handle_size; /* Taille de la séparation */
- panel_node *main_node; /* Branche principale */
- gint position; /* Position de la séparation */
- bool can_lower; /* Diminution possible ? */
- bool can_upper; /* Augmentation possible ? */
- GtkAllocation allocation; /* Taille allouée */
-
- /* Pour les cas simple, GTK gère très bien... */
- if (node->simple) return;
-
- get_panel_node_size_request(node->first, &first_req);
- get_panel_node_size_request(node->second, &second_req);
- gtk_widget_style_get(node->paned, "handle-size", &handle_size, NULL);
- /**
- * Définitions des bornes dans chacun des cas.
- */
+ fprintf(stderr, "Passage avec %p\n", _nodes);
- main_node = find_main_panel_node_branch(node->first, node->second);
-
- /* Le premier noeud est le principal... */
- if (node->first == main_node)
+ return;
+ void store_handle_position(panel_node *node, GGenConfig *config)
{
- if (HAS_H_ORIENTATION(node->paned))
- position = (space->width * MAIN_PART_PERCENT) / 100;
- else
- position = (space->height * MAIN_PART_PERCENT) / 100;
- can_lower = false;
- can_upper = true;
+ size_t i;
- }
+ for (i = 0; i < 0/*node->depth*/; i++)
+ fprintf(stderr, " ");
- /* Le second noeud est le principal... */
- else if (node->second == main_node)
- {
- if (HAS_H_ORIENTATION(node->paned))
- position = space->width - (space->width * MAIN_PART_PERCENT) / 100;
- else
- position = space->height - (space->height * MAIN_PART_PERCENT) / 100;
- can_lower = true;
- can_upper = false;
+ ///fprintf(stderr, "[%s] %s\n", node->path, node->simple ? "[+]" : ">>");
- }
- /* Les éléments sont quelconques... */
- else
- {
- if (HAS_H_ORIENTATION(node->paned))
- position = space->width / 2;
- else
- position = space->height / 2;
-
- can_lower = true;
- can_upper = true;
-
- }
-
- /**
- * Calcul des valeurs applicables et mise en application.
- */
-
- /* Correctifs éventuels pour les petits composants */
- if (node->first == main_node)
- {
- if (HAS_H_ORIENTATION(node->paned))
- second_req.width = MAX(second_req.width, (space->width * MIN_PART_PERCENT) / 100);
- else
- second_req.height = MAX(second_req.height, (space->height * MIN_PART_PERCENT) / 100);
- }
- else if (node->second == main_node)
- {
- if (HAS_H_ORIENTATION(node->paned))
- first_req.width = MAX(first_req.width, (space->width * MIN_PART_PERCENT) / 100);
- else
- first_req.height = MAX(first_req.height, (space->height * MIN_PART_PERCENT) / 100);
- }
+ if (0/*!node->simple*/)
+ {
+ store_handle_position(node->first, config);
+ store_handle_position(node->second, config);
+ }
- /* Une partie principale arrive en premier */
- if (!can_lower && can_upper)
- {
- if (HAS_H_ORIENTATION(node->paned))
- position = MAX(position, space->width - second_req.width - handle_size);
- else
- position = MAX(position, space->height - second_req.height - handle_size);
- }
- /* Une partie principale arrive en second */
- else if (can_lower && !can_upper)
- {
- if (HAS_H_ORIENTATION(node->paned))
- position = MIN(position, second_req.width + handle_size);
- else
- position = MIN(position, second_req.height + handle_size);
}
- /* Chacun pour soit ! */
- else
- {
+ //get_main_configuration()
- /* TODO */;
+ store_handle_position(_nodes, NULL);
+ fflush(NULL);
- }
- gtk_paned_set_position(GTK_PANED(node->paned), position);
+}
- gtk_widget_get_allocation(GET_PANEL_NODE_WIDGET(node->first), &allocation);
- set_panel_node_size_request(node->first, ALLOC_2_REQ(&allocation));
+#endif
- gtk_widget_get_allocation(GET_PANEL_NODE_WIDGET(node->second), &allocation);
- set_panel_node_size_request(node->second, ALLOC_2_REQ(&allocation));
-}
diff --git a/src/gui/panels/panel.h b/src/gui/panels/panel.h
index 0bf5cb5..baf5fe7 100644
--- a/src/gui/panels/panel.h
+++ b/src/gui/panels/panel.h
@@ -26,6 +26,9 @@
#define _GUI_PANELS_PANEL_H
+#include <stdbool.h>
+
+
#include "../editem.h"
@@ -45,11 +48,31 @@ typedef struct _GPanelItem GPanelItem;
typedef struct _GPanelItemClass GPanelItemClass;
+/* Types de panneaux pour éditeur */
+typedef enum _PanelItemPersonality
+{
+ PIP_INVALID, /* Information non initialisée */
+
+ PIP_SINGLETON, /* Instance unique */
+ PIP_BINARY_VIEW, /* Affichage d'un binaire */
+ PIP_OTHER, /* Reste du monde */
+
+ PIP_COUNT
+
+} PanelItemPersonality;
+
+
/* Indique le type défini pour un élément destiné à un panneau. */
GType g_panel_item_get_type(void);
/* Crée un élément de panneau réactif. */
-GEditorItem *g_panel_item_new(GObject *, const char *, const char *, GtkWidget *, const char *);
+GEditorItem *g_panel_item_new(PanelItemPersonality, GObject *, const char *, const char *, GtkWidget *, const char *);
+
+/* Fournit une indication sur la personnalité du panneau. */
+PanelItemPersonality gtk_panel_item_get_personality(const GPanelItem *);
+
+/* Indique la définition d'un éventuel raccourci clavier. */
+const char *gtk_panel_item_get_key_bindings(const GPanelItem *);
/* Recherche un panneau à partir de son nom court. */
GPanelItem *g_panel_item_get(const char *);
@@ -57,11 +80,25 @@ GPanelItem *g_panel_item_get(const char *);
/* Place un panneau dans l'ensemble affiché. */
void g_panel_item_dock(GPanelItem *);
+/* Indique si le composant repose sur un support de l'éditeur. */
+bool g_panel_item_is_docked(const GPanelItem *);
+
/* Supprime un panneau de l'ensemble affiché. */
void g_panel_item_undock(GPanelItem *);
+
+
+
+
+void save_panel_nodes(void);
+
+
+
+
+
+
/* ----------------------- PLACEMENTS DES DIFFERENTS PANNEAUX ----------------------- */
@@ -72,5 +109,12 @@ GtkWidget *init_panels2(GCallback, gpointer);
void load_main_panels(GObject *);
+/* Réalise un traitement sur un panneau de l'éditeur. */
+typedef bool (* handle_panel_item_fc) (GPanelItem *, void *);
+
+/* Effectue le parcours de tous les panneaux chargés. */
+bool browse_all_item_panels(handle_panel_item_fc, void *);
+
+
#endif /* _GUI_PANELS_PANEL_H */
diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c
index a187a2d..cb4fe85 100644
--- a/src/gui/panels/regedit.c
+++ b/src/gui/panels/regedit.c
@@ -204,6 +204,7 @@ static void g_regedit_panel_class_init(GRegeditPanelClass *klass)
static void g_regedit_panel_init(GRegeditPanel *panel)
{
GEditorItem *base; /* Version basique d'instance */
+ GPanelItem *pitem; /* Version parente du panneau */
GObject *ref; /* Espace de référencement */
GtkWidget *label; /* Etiquette à utiliser */
GtkWidget *search; /* Zone de recherche */
@@ -224,6 +225,10 @@ static void g_regedit_panel_init(GRegeditPanel *panel)
ref = G_OBJECT(base->widget);
g_object_set_data(ref, "panel", panel);
+ pitem = G_PANEL_ITEM(panel);
+
+ pitem->personality = PIP_SINGLETON;
+
/* Partie recherche */
label = qck_create_label(NULL, NULL, _("Look for:"));
@@ -386,7 +391,7 @@ GEditorItem *g_regedit_panel_new(GObject *ref)
result = g_object_new(G_TYPE_REGEDIT_PANEL, NULL);
g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_REGEDIT_ID,
- _("Configuration parameters"), G_EDITOR_ITEM(result)->widget, "M");
+ _("Configuration parameters"), G_EDITOR_ITEM(result)->widget, "N");
reload_config_into_treeview(G_REGEDIT_PANEL(result), get_main_configuration());
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index abbf7ed..9759e71 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -179,6 +179,7 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass)
{
GObjectClass *object; /* Autre version de la classe */
GEditorItemClass *editem; /* Encore une autre vision... */
+ GPanelItemClass *panel; /* Version parente de la classe*/
object = G_OBJECT_CLASS(klass);
@@ -189,6 +190,11 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass)
editem->update_binary = (update_item_binary_fc)change_strings_panel_current_binary;
+ panel = G_PANEL_ITEM_CLASS(klass);
+
+ panel->unique = true;
+ panel->bindings = "<Shift>F12";
+
}
@@ -207,6 +213,7 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass)
static void g_strings_panel_init(GStringsPanel *panel)
{
GEditorItem *base; /* Version basique d'instance */
+ GPanelItem *pitem; /* Version parente du panneau */
GObject *ref; /* Espace de référencement */
GtkTreeStore *store; /* Modèle de gestion */
GtkWidget *treeview; /* Affichage de la liste */
@@ -227,6 +234,10 @@ static void g_strings_panel_init(GStringsPanel *panel)
ref = G_OBJECT(base->widget);
g_object_set_data(ref, "panel", panel);
+ pitem = G_PANEL_ITEM(panel);
+
+ pitem->personality = PIP_SINGLETON;
+
/* Partie chaînes */
store = gtk_tree_store_new(STC_COUNT, G_TYPE_OBJECT,
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index 2a9d612..eebfc4c 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -181,6 +181,7 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass)
GObjectClass *object; /* Autre version de la classe */
GEditorItemClass *editem; /* Encore une autre vision... */
gchar *filename; /* Chemin d'accès à utiliser */
+ GPanelItemClass *panel; /* Version parente de la classe*/
object = G_OBJECT_CLASS(klass);
@@ -212,6 +213,11 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass)
g_free(filename);
+ panel = G_PANEL_ITEM_CLASS(klass);
+
+ panel->unique = true;
+ panel->bindings = "<Shift>F3";
+
}
@@ -230,6 +236,7 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass)
static void g_symbols_panel_init(GSymbolsPanel *panel)
{
GEditorItem *base; /* Version basique d'instance */
+ GPanelItem *pitem; /* Version parente du panneau */
GObject *ref; /* Espace de référencement */
GtkWidget *box; /* Séparation horizontale */
GtkWidget *toolbar; /* Barre d'outils */
@@ -250,6 +257,10 @@ static void g_symbols_panel_init(GSymbolsPanel *panel)
ref = G_OBJECT(base->widget);
g_object_set_data(ref, "panel", panel);
+ pitem = G_PANEL_ITEM(panel);
+
+ pitem->personality = PIP_SINGLETON;
+
/* Barre d'outils supérieure */
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
@@ -435,7 +446,7 @@ GEditorItem *g_symbols_panel_new(GObject *ref)
result = g_object_new(G_TYPE_SYMBOLS_PANEL, NULL);
g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_SYMBOLS_ID,
- _("Binary symbols"), G_EDITOR_ITEM(result)->widget, "eM");
+ _("Binary symbols"), G_EDITOR_ITEM(result)->widget, "eN");
return result;