From 50a657889a32a6df365bf9880a6f56bf3a0e828c Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 13 Aug 2015 00:35:42 +0000 Subject: Improved the look of dock stations and saved screen space. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@571 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 23 +++ src/gtkext/Makefile.am | 2 + src/gtkext/easygtk.c | 186 ++++++++++++++++++--- src/gtkext/easygtk.h | 8 +- src/gtkext/gtkdockable-int.h | 69 ++++++++ src/gtkext/gtkdockable.c | 381 +++++++++++++++++++++++++++++++++++++++++++ src/gtkext/gtkdockable.h | 72 ++++++++ src/gtkext/gtkdockstation.c | 157 +++++++++++++----- src/gtkext/gtkdockstation.h | 9 +- src/gui/panels/bookmarks.c | 163 +++++++++--------- src/gui/panels/panel.c | 108 +++++++++++- src/gui/panels/strings.c | 137 +++++++--------- 12 files changed, 1060 insertions(+), 255 deletions(-) create mode 100644 src/gtkext/gtkdockable-int.h create mode 100644 src/gtkext/gtkdockable.c create mode 100644 src/gtkext/gtkdockable.h diff --git a/ChangeLog b/ChangeLog index dac9be0..917cfba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +15-08-13 Cyrille Bagard + + * src/gtkext/easygtk.c: + * src/gtkext/easygtk.h: + Build toggle buttons with images, too. + + * src/gtkext/gtkdockable.c: + * src/gtkext/gtkdockable.h: + * src/gtkext/gtkdockable-int.h: + New entries: define a GObject interface for dockable widgets. + + * src/gtkext/gtkdockstation.c: + * src/gtkext/gtkdockstation.h: + Improve the look of dock stations and save screen space. + + * src/gtkext/Makefile.am: + Add the 'gtkdockable*[ch]' files from libgtkext_la_SOURCES. + + * src/gui/panels/bookmarks.c: + * src/gui/panels/panel.c: + * src/gui/panels/strings.c: + Implement the new interface and update the code. + 15-08-12 Cyrille Bagard * plugins/pychrysa/arch/instruction.c: diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index 6d713d9..6849585 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -8,6 +8,8 @@ libgtkext_la_SOURCES = \ gtkblockview.h gtkblockview.c \ gtkbufferview-int.h \ gtkbufferview.h gtkbufferview.c \ + gtkdockable-int.h \ + gtkdockable.h gtkdockable.c \ gtkdockstation.h gtkdockstation.c \ gtkgraphview.h gtkgraphview.c \ gtksourceview.h gtksourceview.c \ diff --git a/src/gtkext/easygtk.c b/src/gtkext/easygtk.c index fcbaa19..61e8953 100644 --- a/src/gtkext/easygtk.c +++ b/src/gtkext/easygtk.c @@ -28,6 +28,10 @@ +/* Termine la construction d'un composant 'GtkButton'. */ +static void _finish_button_with_img(GtkWidget *, GObject *, const char *, GtkWidget *, const char *); + + /****************************************************************************** * * @@ -399,6 +403,113 @@ GtkWidget *qck_create_button_with_img(GObject *object, const char *name, const c /****************************************************************************** * * +* Paramètres : button = composant graphique dont la définition est à finir.* +* object = espace dédié à l'inscription de références. * +* name = nom à donner au nouveau composant. * +* picture = éventuelle image sous forme de composant GTK. * +* label = contenu de l'étiquette éventuelle associée. * +* * +* Description : Termine la construction d'un composant 'GtkButton'. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _finish_button_with_img(GtkWidget *button, GObject *object, const char *name, GtkWidget *picture, const char *label) +{ + GtkWidget *caption; /* Etiquette à coller */ + GtkWidget *hbox; /* Séparation horizontale */ + + /* Création des éléments internes (2/2) */ + + if (label != NULL) + { + caption = gtk_label_new_with_mnemonic(label); + gtk_widget_show(caption); + } + + /* Mise en place */ + + if (picture != NULL && label != NULL) + { + hbox = gtk_hbox_new(FALSE, 2); + gtk_widget_show(hbox); + gtk_container_add(GTK_CONTAINER(button), hbox); + + gtk_box_pack_start(GTK_BOX(hbox), picture, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), caption, FALSE, FALSE, 0); + + } + + else if (picture != NULL) + gtk_container_add(GTK_CONTAINER(button), picture); + + else /*if (label != NULL)*/ + gtk_container_add(GTK_CONTAINER(button), caption); + + /* Interactions GTK... */ + + if (G_IS_OBJECT(object) && name != NULL) + { + g_object_ref(G_OBJECT(button)); + g_object_set_data_full(object, name, button, (GDestroyNotify)g_object_unref); + } + + gtk_widget_show(button); + +} + + +/****************************************************************************** +* * +* Paramètres : object = espace dédié à l'inscription de références. * +* name = nom à donner au nouveau composant. * +* image = nom de l'image stockée dans GTK. * +* size = taille de l'image éventuelle à faire figurer. * +* label = contenu de l'étiquette éventuelle associée. * +* handler = éventuelle fonction de sélection associée. * +* data = données à transmettre avec l'événement si besoin. * +* * +* Description : Crée et enregistre un composant 'GtkButton'. * +* * +* Retour : Simple bouton mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *qck_create_button_with_named_img(GObject *object, const char *name, const char *image, GtkIconSize size, const char *label, GCallback handler, gpointer data) +{ + GtkWidget *result; /* Résultat à renvoyer */ + GtkWidget *picture; /* Image de représentation */ + + result = gtk_button_new(); + gtk_widget_set_can_default(result, TRUE); + + /* Création des éléments internes (1/2) */ + + if (image != NULL) + { + picture = gtk_image_new_from_icon_name(image, size); + gtk_widget_show(picture); + } + else + picture = NULL; + + _finish_button_with_img(result, object, name, picture, label); + + if (handler != NULL) + g_signal_connect(result, "clicked", handler, data); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : object = espace dédié à l'inscription de références. * * name = nom à donner au nouveau composant. * * image = nom de l'image stockée dans GTK. * @@ -418,13 +529,11 @@ GtkWidget *qck_create_button_with_css_img(GObject *object, const char *name, con { GtkWidget *result; /* Résultat à renvoyer */ GtkWidget *picture; /* Image de représentation */ - GtkWidget *caption; /* Etiquette à coller */ - GtkWidget *hbox; /* Séparation horizontale */ result = gtk_button_new(); gtk_widget_set_can_default(result, TRUE); - /* Création des éléments internes */ + /* Création des éléments internes (1/2) */ if (image != NULL) { @@ -434,44 +543,59 @@ GtkWidget *qck_create_button_with_css_img(GObject *object, const char *name, con gtk_widget_set_name(picture, image); } + else + picture = NULL; - if (label != NULL) - { - caption = gtk_label_new_with_mnemonic(label); - gtk_widget_show(caption); - } + _finish_button_with_img(result, object, name, picture, label); - /* Mise en place */ + if (handler != NULL) + g_signal_connect(result, "clicked", handler, data); - if (image != NULL && label != NULL) - { - hbox = gtk_hbox_new(FALSE, 2); - gtk_widget_show(hbox); - gtk_container_add(GTK_CONTAINER(result), hbox); + return result; - gtk_box_pack_start(GTK_BOX(hbox), picture, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(hbox), caption, FALSE, FALSE, 0); +} - } - else if (image != NULL) - gtk_container_add(GTK_CONTAINER(result), picture); +/****************************************************************************** +* * +* Paramètres : object = espace dédié à l'inscription de références. * +* name = nom à donner au nouveau composant. * +* image = nom de l'image stockée dans GTK. * +* size = taille de l'image éventuelle à faire figurer. * +* label = contenu de l'étiquette éventuelle associée. * +* handler = éventuelle fonction de sélection associée. * +* data = données à transmettre avec l'événement si besoin. * +* * +* Description : Crée et enregistre un composant 'GtkCheckButton'. * +* * +* Retour : Simple bouton mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *qck_create_toggle_button_with_named_img(GObject *object, const char *name, const char *image, GtkIconSize size, const char *label, GCallback handler, gpointer data) +{ + GtkWidget *result; /* Résultat à renvoyer */ + GtkWidget *picture; /* Image de représentation */ - else /*if (label != NULL)*/ - gtk_container_add(GTK_CONTAINER(result), caption); + result = gtk_toggle_button_new(); + gtk_widget_set_can_default(result, TRUE); - /* Interactions GTK... */ + /* Création des éléments internes (1/2) */ - if (G_IS_OBJECT(object) && name != NULL) + if (image != NULL) { - g_object_ref(G_OBJECT(result)); - g_object_set_data_full(object, name, result, (GDestroyNotify)g_object_unref); + picture = gtk_image_new_from_icon_name(image, size); + gtk_widget_show(picture); } + else + picture = NULL; - gtk_widget_show(result); + _finish_button_with_img(result, object, name, picture, label); if (handler != NULL) - g_signal_connect(result, "clicked", handler, data); + g_signal_connect(result, "toggled", handler, data); return result; @@ -802,6 +926,14 @@ void add_accelerator_to_menu_item(GtkWidget *item, const char *accelerator, GtkA gtk_accelerator_parse(accelerator, &key, &mods); + + gboolean force_accel_activation(GtkWidget *widget, guint signal_id, gpointer data) + { + return TRUE; + } + + g_signal_connect(item, "can-activate-accel", force_accel_activation, NULL); + gtk_widget_add_accelerator(item, "activate", group, key, mods, GTK_ACCEL_VISIBLE); diff --git a/src/gtkext/easygtk.h b/src/gtkext/easygtk.h index 58229af..13cb7fd 100644 --- a/src/gtkext/easygtk.h +++ b/src/gtkext/easygtk.h @@ -60,12 +60,18 @@ GtkWidget *qck_create_textview(GObject *, const char *, GCallback, gpointer); GtkWidget *qck_create_button(GObject *, const char *, const char *, GCallback, gpointer); /* Crée et enregistre un composant 'GtkButton'. */ -GtkWidget *qck_create_button_with_img(GObject *, const char *, const char *, GCallback, gpointer); +GtkWidget *qck_create_button_with_img(GObject *, const char *, const char *, GCallback, gpointer) __attribute__ ((deprecated)); + +/* Crée et enregistre un composant 'GtkButton'. */ +GtkWidget *qck_create_button_with_named_img(GObject *, const char *, const char *, GtkIconSize, const char *, GCallback, gpointer); /* Crée et enregistre un composant 'GtkButton'. */ GtkWidget *qck_create_button_with_css_img(GObject *, const char *, const char *, const char *, GCallback, gpointer); /* Crée et enregistre un composant 'GtkCheckButton'. */ +GtkWidget *qck_create_toggle_button_with_named_img(GObject *, const char *, const char *, GtkIconSize, const char *, GCallback, gpointer); + +/* Crée et enregistre un composant 'GtkCheckButton'. */ GtkWidget *qck_create_check_button(GObject *, const char *, const char *, GCallback, gpointer); /* Crée et enregistre un composant 'GtkRadioButton'. */ diff --git a/src/gtkext/gtkdockable-int.h b/src/gtkext/gtkdockable-int.h new file mode 100644 index 0000000..95e1d0c --- /dev/null +++ b/src/gtkext/gtkdockable-int.h @@ -0,0 +1,69 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdockable-int.h - définitions internes propres aux éléments acceptés dans les composants de rassemblement + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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 3 of the License, or + * (at your option) any later version. + * + * OpenIDA 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 Foobar. If not, see . + */ + + +#ifndef _GTK_DOCKABLE_INT_H +#define _GTK_DOCKABLE_INT_H + + +#include "gtkdockable.h" + + +#include + + + +/* Fournit le nom court du composant encapsulable. */ +typedef const char * (* get_dockable_name_fc) (const GtkDockable *); + +/* Fournit le nom court du composant encapsulable. */ +typedef const char * (* get_dockable_desc_fc) (const GtkDockable *); + +/* Fournit le composant principal à encapsuler au besoin. */ +typedef GtkWidget * (* get_dockable_widget_fc) (const GtkDockable *); + +/* Démarre l'actualisation du filtrage des paramètres. */ +typedef void (* update_filtered_data_fc) (GtkDockable *, const regex_t *); + + +/* Elément accepté dans les rassemblements (interface) */ +struct _GtkDockableIface +{ + GTypeInterface base_iface; /* A laisser en premier */ + + bool can_search; /* Contenu fouillable ? */ + bool can_be_closed; /* Fermeture possible ? */ + + get_dockable_name_fc get_name; /* Nom pour titre */ + get_dockable_desc_fc get_desc; /* Description humaine */ + get_dockable_widget_fc get_widget; /* Composant à représenter */ + update_filtered_data_fc update_filtered;/* Mise à jour du filtrage */ + +}; + + +/* Redéfinition */ +typedef GtkDockableIface GtkDockableInterface; + + + +#endif /* _GTK_DOCKABLE_INT_H */ diff --git a/src/gtkext/gtkdockable.c b/src/gtkext/gtkdockable.c new file mode 100644 index 0000000..8819108 --- /dev/null +++ b/src/gtkext/gtkdockable.c @@ -0,0 +1,381 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdockable.c - éléments acceptés dans les composants de rassemblement + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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 3 of the License, or + * (at your option) any later version. + * + * OpenIDA 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 Foobar. If not, see . + */ + + +#include "gtkdockable.h" + + +#include +#include + + +#include + + +#include "easygtk.h" +#include "gtkdockable-int.h" + + + +/* --------------------- DEFINITIONS PRINCIPALES DE L'INTERFACE --------------------- */ + + +/* Procède à l'initialisation de l'interface de rassemblement. */ +static void gtk_dockable_default_init(GtkDockableInterface *); + + + +/* ------------------------ FONCTIONS DE RECHERCHE INTEGREES ------------------------ */ + + +/* Construit une zone de recherches vouée à être intégrée. */ +static GtkWidget *build_search_area(GtkDockable *, GtkWidget **); + +/* Met à jour l'expression de filtrage de la zone intégrée. */ +static void on_dockable_search_changed(GtkSearchEntry *, GtkDockable *); + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITIONS PRINCIPALES DE L'INTERFACE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type d'une interface pour rassemblement. */ +G_DEFINE_INTERFACE(GtkDockable, gtk_dockable, G_TYPE_OBJECT) + + +/****************************************************************************** +* * +* Paramètres : iface = interface GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de rassemblement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_dockable_default_init(GtkDockableInterface *iface) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le nom court du composant encapsulable. * +* * +* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *gtk_dockable_get_name(const GtkDockable *dockable) +{ + GtkDockableIface *iface; /* Interface utilisée */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + return iface->get_name(dockable); + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le nom long du composant encapsulable. * +* * +* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *gtk_dockable_get_desc(const GtkDockable *dockable) +{ + GtkDockableIface *iface; /* Interface utilisée */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + return iface->get_desc(dockable); + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Indique si le composant représenté à du contenu à fouiller. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_dockable_can_search(const GtkDockable *dockable) +{ + GtkDockableIface *iface; /* Interface utilisée */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + return iface->can_search; + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Indique si le composant peut être désencapsulé manuellement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_dockable_can_be_closed(const GtkDockable *dockable) +{ + GtkDockableIface *iface; /* Interface utilisée */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + return iface->can_be_closed; + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le composant graphique intégrable dans un ensemble. * +* * +* Retour : Composant graphique prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *gtk_dockable_get_widget(GtkDockable *dockable) +{ + GtkWidget *result; /* Composant à retourner */ + GtkDockableIface *iface; /* Interface utilisée */ + GtkWidget *widget; /* Composant graphique interne */ + GtkWidget *revealer; /* Révélateur à intégrer ? */ + GtkWidget *search; /* Zone de recherche */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + widget = iface->get_widget(dockable); + g_object_ref(G_OBJECT(widget)); + + /* Encapsulation avec un panneau coulissant ? */ + + if (iface->can_search) + { + revealer = gtk_revealer_new(); + gtk_widget_show(revealer); + + gtk_container_add(GTK_CONTAINER(revealer), build_search_area(dockable, &search)); + + result = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_show(result); + + gtk_box_pack_start(GTK_BOX(result), revealer, FALSE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(result), widget, TRUE, TRUE, 0); + + g_object_set_data(G_OBJECT(result), "revealer", revealer); + g_object_set_data(G_OBJECT(result), "search", search); + + } + + /* Ou bien non ! */ + else + result = widget; + + 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. * +* * +* Description : Révèle ou cache la zone de recherches. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_dockable_toggle_revealer(GtkDockable *dockable, GtkWidget *built, gboolean reveal) +{ + GtkRevealer *revealer; /* Révélateur à actionner */ + GtkWidget *entry; /* Zone de recherche à activer */ + + revealer = GTK_REVEALER(g_object_get_data(G_OBJECT(built), "revealer")); + assert(revealer != NULL); + + gtk_revealer_set_reveal_child(revealer, reveal); + + if (reveal) + { + entry = GTK_WIDGET(g_object_get_data(G_OBJECT(built), "search")); + gtk_widget_grab_focus(entry); + } + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* FONCTIONS DE RECHERCHE INTEGREES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : dockable = élément encapsulable à avertir des changements. * +* search = zone de saisie pour lancer les recherches. * +* * +* Description : Construit une zone de recherches vouée à être intégrée. * +* * +* Retour : Composant GTK prêt à être intégré. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *build_search_area(GtkDockable *dockable, GtkWidget **search) +{ + GtkWidget *result; /* Support à retourner */ + GtkWidget *label; /* Etiquette à utiliser */ + + result = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(result), 8); + gtk_widget_show(result); + + label = qck_create_label(NULL, NULL, _("Look for:")); + g_object_set(label, "margin", 8, NULL); + gtk_grid_attach(GTK_GRID(result), label, 0, 0, 1, 1); + + *search = gtk_search_entry_new(); + g_signal_connect(*search, "search-changed", G_CALLBACK(on_dockable_search_changed), dockable); + gtk_widget_set_hexpand(*search, TRUE); + gtk_widget_show(*search); + gtk_grid_attach_next_to(GTK_GRID(result), *search, label, GTK_POS_RIGHT, 1, 1); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : entry = entrée de texte contenant le filtre brut. * +* Paramètres : dockable = élément encapsulable à avertir des changements. * +* * +* Description : Met à jour l'expression de filtrage de la zone intégrée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_dockable_search_changed(GtkSearchEntry *entry, GtkDockable *dockable) +{ + regex_t *filter; /* Expression régulière */ + const gchar *text; /* Texte de l'utilisateur */ + int ret; /* Bilan de mise en place */ + GdkRGBA error; /* Couleur d'erreur */ + GtkDockableIface *iface; /* Interface utilisée */ + + filter = g_object_get_data(G_OBJECT(entry), "preg_filter"); + + text = gtk_entry_get_text(GTK_ENTRY(entry)); + + /* Mise en place d'une nouvelle règle */ + if (strlen(text) > 0) + { + if (filter == NULL) + { + void destroy_filter(regex_t *preg) + { + regfree(preg); + free(preg); + } + + filter = (regex_t *)calloc(1, sizeof(regex_t)); + g_object_set_data_full(G_OBJECT(entry), "preg_filter", filter, (GDestroyNotify)destroy_filter); + + } + else + regfree(filter); + + ret = regcomp(filter, text, REG_EXTENDED); + + if (ret != 0) + { + error.red = 1.0; + error.green = 0.0; + error.blue = 0.0; + error.alpha = 1.0; + gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error); + + return; + + } + + } + + /* Suppresion de toute règle existante */ + else if (filter != NULL) + { + g_object_set_data(G_OBJECT(entry), "preg_filter", NULL); + filter = NULL; + } + + /* Mises à jour */ + + gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL); + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + iface->update_filtered(dockable, filter); + +} diff --git a/src/gtkext/gtkdockable.h b/src/gtkext/gtkdockable.h new file mode 100644 index 0000000..91a6bda --- /dev/null +++ b/src/gtkext/gtkdockable.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdockable.h - prototypes pour les éléments acceptés dans les composants de rassemblement + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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 3 of the License, or + * (at your option) any later version. + * + * OpenIDA 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 Foobar. If not, see . + */ + + +#ifndef _GTKEXT_GTKDOCKABLE_H +#define _GTKEXT_GTKDOCKABLE_H + + +#include +#include + + + +#define GTK_TYPE_DOCKABLE (gtk_dockable_get_type()) +#define GTK_DOCKABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_DOCKABLE, GtkDockable)) +#define GTK_DOCKABLE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), GTK_TYPE_DOCKABLE, GtkDockableIface)) +#define GTK_IS_DOCKABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_DOCKABLE)) +#define GTK_IS_DOCKABLE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), GTK_TYPE_DOCKABLE)) +#define GTK_DOCKABLE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), GTK_TYPE_DOCKABLE, GtkDockableIface)) + + +/* Elément accepté dans les rassemblements (coquille vide) */ +typedef struct _GtkDockable GtkDockable; + +/* Elément accepté dans les rassemblements (interface) */ +typedef struct _GtkDockableIface GtkDockableIface; + + + +/* Détermine le type d'une interface pour rassemblement. */ +GType gtk_dockable_get_type(void) G_GNUC_CONST; + +/* Indique si le composant représenté à du contenu à fouiller. */ +bool gtk_dockable_can_search(const GtkDockable *); + +/* Indique si le composant peut être désencapsulé manuellement. */ +bool gtk_dockable_can_be_closed(const GtkDockable *); + +/* Fournit le nom court du composant encapsulable. */ +const char *gtk_dockable_get_name(const GtkDockable *); + +/* Fournit le nom long du composant encapsulable. */ +const char *gtk_dockable_get_desc(const GtkDockable *); + +/* Fournit le composant graphique intégrable dans un ensemble. */ +GtkWidget *gtk_dockable_get_widget(GtkDockable *); + +/* Révèle ou cache la zone de recherches. */ +void gtk_dockable_toggle_revealer(GtkDockable *, GtkWidget *, gboolean); + + + +#endif /* _GTKEXT_GTKDOCKABLE_H */ diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c index 2737557..e10e55f 100644 --- a/src/gtkext/gtkdockstation.c +++ b/src/gtkext/gtkdockstation.c @@ -42,7 +42,17 @@ static void gtk_dock_station_class_init(GtkDockStationClass *); static void gtk_dock_station_init(GtkDockStation *); /* Met à jour le titre du support de panneaux concentrés. */ -static gboolean gtk_dock_station_switch_panel(GtkNotebook *, gpointer *, guint, gpointer); +static gboolean gtk_dock_station_switch_panel(GtkNotebook *, gpointer *, guint, GtkDockStation *); + + + + +/* Révèle ou cache la zone de recherches. */ +static void on_toggle_revealer(GtkToggleButton *, GtkDockStation *); + + + + @@ -114,7 +124,7 @@ static void gtk_dock_station_init(GtkDockStation *station) eventbox = gtk_event_box_new(); gtk_widget_show(eventbox); - gtk_box_pack_start(GTK_BOX(station), eventbox, FALSE, TRUE, 0); + //gtk_box_pack_start(GTK_BOX(station), eventbox, FALSE, TRUE, 0); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_widget_show(hbox); @@ -144,13 +154,42 @@ static void gtk_dock_station_init(GtkDockStation *station) 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_tab_pos(station->notebook, GTK_POS_BOTTOM); gtk_notebook_set_scrollable(station->notebook, TRUE); + /* Définition de la zone de contrôle */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_set_valign(hbox, GTK_ALIGN_CENTER); + gtk_widget_set_margin_end(hbox, 8); + gtk_widget_show(hbox); + + button = qck_create_toggle_button_with_named_img(G_OBJECT(station), "search", + "edit-find-symbolic", GTK_ICON_SIZE_MENU, NULL, + G_CALLBACK(on_toggle_revealer), station); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + button = qck_create_button_with_named_img(G_OBJECT(station), "menu", + "go-down-symbolic", GTK_ICON_SIZE_MENU, NULL, + G_CALLBACK(NULL), station); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + button = qck_create_button_with_named_img(G_OBJECT(station), "close", + "window-close-symbolic", GTK_ICON_SIZE_MENU, NULL, + G_CALLBACK(NULL), 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); + g_signal_connect(station->notebook, "switch-page", G_CALLBACK(gtk_dock_station_switch_panel), station); @@ -181,7 +220,7 @@ GtkWidget *gtk_dock_station_new(void) * Paramètres : notebook = support à l'origine de la mise à jour. * * page = onglet mis en avant. * * index = indice de l'onglet actuellement actif. * -* data = adresse du conteneur supérieur. * +* station = conteneur de gestion supérieur. * * * * Description : Met à jour le titre du support de panneaux concentrés. * * * @@ -191,17 +230,35 @@ GtkWidget *gtk_dock_station_new(void) * * ******************************************************************************/ -static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *page, guint index, gpointer data) +static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *page, guint index, GtkDockStation *station) { GtkWidget *widget; /* Panneau concerné */ - char *str; /* Texte à redonner */ + GtkDockable *dockable; /* Elément encapsulé */ + GtkWidget *button; /* Bouton de contrôle */ widget = gtk_notebook_get_nth_page(notebook, index); - str = g_object_get_data(G_OBJECT(widget), "title"); - gtk_dock_panel_update_title(GTK_DOCK_STATION(data), widget, str); + dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable")); + + /* Mise à jour des boutons utilisables */ - g_signal_emit_by_name(GTK_DOCK_STATION(data), "switch-widget", widget); + button = GTK_WIDGET(g_object_get_data(G_OBJECT(station), "search")); + + if (gtk_dockable_can_search(dockable)) + gtk_widget_show(button); + else + gtk_widget_hide(button); + + button = GTK_WIDGET(g_object_get_data(G_OBJECT(station), "close")); + + if (gtk_dockable_can_be_closed(dockable)) + gtk_widget_show(button); + else + gtk_widget_hide(button); + + /* Remontée du changement d'onglet */ + + g_signal_emit_by_name(station, "switch-widget", widget); return TRUE; @@ -223,12 +280,26 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p * * ******************************************************************************/ -void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const char *caption, const char *desc) +void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockable) { + GtkWidget *widget; /* Composant GTK à intégrer */ + const char *caption; /* Nom à donner à l'onglet */ + const char *desc; /* Description à y associer */ size_t max; /* Taille maximale des titres */ char *str; /* Titre des prochaines fois */ GtkWidget *label; /* Etiquette d'onglet */ + /* Récupération des éléments utiles */ + + widget = gtk_dockable_get_widget(dockable); + + g_object_set_data(G_OBJECT(widget), "dockable", dockable); + + caption = gtk_dockable_get_name(dockable); + desc = gtk_dockable_get_desc(dockable); + + /* Mise en place de la page */ + if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_TAB, &max)) max = -1; @@ -236,28 +307,22 @@ void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const 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, G_CALLBACK(gtk_dock_station_switch_panel), station); gtk_notebook_insert_page(station->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", G_CALLBACK(gtk_dock_station_switch_panel), station); - gtk_notebook_set_show_tabs(station->notebook, gtk_notebook_get_n_pages(station->notebook) > 1); - - str = g_object_get_data(G_OBJECT(widget), "title"); - if (str != NULL) free(str); - - if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_HEADER, &max)) - max = -1; - - g_object_set_data(G_OBJECT(widget), "title", ellipsis(strdup(desc), max)); + /* Lancement des mises à jour */ - gtk_dock_panel_update_title(station, widget, desc); + if (gtk_notebook_get_n_pages(station->notebook) > 1) + gtk_notebook_set_current_page(station->notebook, -1); - gtk_notebook_set_current_page(station->notebook, -1); g_signal_emit_by_name(station, "dock-widget", widget); @@ -328,13 +393,17 @@ void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget) gint index; /* Indice de l'onglet visé */ gint count; /* Nombre d'onglets en place */ + + return; + + 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); + //gtk_notebook_set_show_tabs(station->notebook, count > 1); if (count == 0) gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(station))), @@ -345,50 +414,48 @@ void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget) /****************************************************************************** * * -* Paramètres : station = plateforme GTK à compléter. * -* widget = nouvel élément à intégrer. * -* caption = intitulé court à afficher sur les onglets. * +* Paramètres : station = plateforme GTK à consulter. * +* index = indice de l'onglet visé. * * * -* Description : Met à jour, si besoin est, le titre de l'affichage concentré.* +* Description : Renvoie un composant intégré dans l'affichage centralisé. * * * -* Retour : - * +* Retour : Composant associé à l'indice donné. * * * * Remarques : - * * * ******************************************************************************/ -void gtk_dock_panel_update_title(GtkDockStation *station, GtkWidget *widget, const char *caption) +GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index) { - char *str; /* Valeur finale reconstituée */ - - str = calloc(strlen("") + strlen(caption) + strlen("") + 1, sizeof(char)); - - strcpy(str, ""); - strcat(str, caption); - strcat(str, ""); - - gtk_label_set_markup(station->title, str); - - free(str); + return gtk_notebook_get_nth_page(station->notebook, index); } /****************************************************************************** * * -* Paramètres : station = plateforme GTK à consulter. * -* index = indice de l'onglet visé. * +* Paramètres : button = bouton à l'origine de la procédure. * +* station = station d'accueil pour différents composants. * * * -* Description : Renvoie un composant intégré dans l'affichage centralisé. * +* Description : Révèle ou cache la zone de recherches. * * * -* Retour : Composant associé à l'indice donné. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index) +static void on_toggle_revealer(GtkToggleButton *button, GtkDockStation *station) { - return gtk_notebook_get_nth_page(station->notebook, index); + 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); + + dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable")); + + gtk_dockable_toggle_revealer(dockable, widget, gtk_toggle_button_get_active(button)); } diff --git a/src/gtkext/gtkdockstation.h b/src/gtkext/gtkdockstation.h index 7cc2263..d64a0b8 100644 --- a/src/gtkext/gtkdockstation.h +++ b/src/gtkext/gtkdockstation.h @@ -28,6 +28,10 @@ #include +#include "gtkdockable.h" + + + //G_BEGIN_DECLS @@ -76,7 +80,7 @@ GType gtk_dock_station_get_type(void); GtkWidget *gtk_dock_station_new(void); /* Ajoute un paquet d'informations à l'affichage centralisé. */ -void gtk_dock_panel_add_widget(GtkDockStation *, GtkWidget *, const char *, const char *); +void gtk_dock_station_add_dockable(GtkDockStation *, GtkDockable *); /* Change le contenu de l'onglet courant uniquement. */ void gtk_dock_panel_change_active_widget(GtkDockStation *, GtkWidget *); @@ -84,9 +88,6 @@ 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 *); -/* Met à jour, si besoin est, le titre de l'affichage concentré. */ -void gtk_dock_panel_update_title(GtkDockStation *, GtkWidget *, const char *); - /* Renvoie un composant intégré dans l'affichage centralisé. */ GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *, gint); diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c index 977cbc9..e06b891 100644 --- a/src/gui/panels/bookmarks.c +++ b/src/gui/panels/bookmarks.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -44,6 +43,7 @@ #include "../../glibext/chrysamarshal.h" #include "../../glibext/signal.h" #include "../../gtkext/easygtk.h" +#include "../../gtkext/gtkdockable-int.h" #include "../../gtkext/support.h" @@ -57,7 +57,7 @@ struct _GBookmarksPanel GPanelItem parent; /* A laisser en premier */ GtkTreeView *treeview; /* Composant d'affichage */ - regex_t *filter; /* Filtre appliqué ou NULL */ + const regex_t *filter; /* Filtre appliqué ou NULL */ GtkMenu *menu; /* Menu contextuel pour param. */ @@ -98,6 +98,9 @@ static void g_bookmarks_panel_class_init(GBookmarksPanelClass *); /* Initialise une instance de panneau de paramètres de config. */ static void g_bookmarks_panel_init(GBookmarksPanel *); +/* Procède à l'initialisation de l'interface de rassemblement. */ +static void g_bookmarks_panel_dockable_interface_init(GtkDockableInterface *); + /* Supprime toutes les références externes. */ static void g_bookmarks_panel_dispose(GBookmarksPanel *); @@ -141,10 +144,10 @@ static void on_param_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkTr /* Démarre l'actualisation du filtrage des paramètres. */ -static void on_param_search_changed(GtkSearchEntry *, GBookmarksPanel *); +static void update_filtered_bookmarks(GBookmarksPanel *, const regex_t *); -/* Détermine si un paramètre doit être filtré ou non. */ -static bool is_param_filtered(GBookmarksPanel *, const char *); +/* Détermine si un signet doit être filtré ou non. */ +static bool is_bookmark_filtered(GBookmarksPanel *, const char *, const char *, const char *); @@ -177,7 +180,8 @@ static void mcb_bookmarks_panel_filter(GtkMenuItem *, GBookmarksPanel *); /* Indique le type définit pour un panneau d'affichage des signets liés à un binaire. */ -G_DEFINE_TYPE(GBookmarksPanel, g_bookmarks_panel, G_TYPE_PANEL_ITEM); +G_DEFINE_TYPE_WITH_CODE(GBookmarksPanel, g_bookmarks_panel, G_TYPE_PANEL_ITEM, + G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_bookmarks_panel_dockable_interface_init)) /****************************************************************************** @@ -233,9 +237,6 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel) { GEditorItem *base; /* Version basique d'instance */ GObject *ref; /* Espace de référencement */ - GtkWidget *label; /* Etiquette à utiliser */ - GtkWidget *search; /* Zone de recherche */ - GtkWidget *scrolled; /* Fenêtre défilante */ GtkTreeStore *store; /* Modèle de gestion */ GtkWidget *treeview; /* Affichage de la liste */ GtkCellRenderer *renderer; /* Moteur de rendu de colonne */ @@ -245,35 +246,16 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel) base = G_EDITOR_ITEM(panel); - base->widget = gtk_grid_new(); + base->widget = gtk_scrolled_window_new(NULL, NULL); gtk_widget_show(base->widget); - gtk_grid_set_row_spacing(GTK_GRID(base->widget), 8); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(base->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(base->widget), GTK_SHADOW_IN); ref = G_OBJECT(base->widget); g_object_set_data(ref, "panel", panel); - /* Partie recherche */ - - label = qck_create_label(NULL, NULL, _("Look for:")); - g_object_set(label, "margin", 8, NULL); - gtk_grid_attach(GTK_GRID(base->widget), label, 0, 0, 1, 1); - - search = gtk_search_entry_new(); - ///g_signal_connect(search, "search-changed", G_CALLBACK(on_param_search_changed), panel); - gtk_widget_show(search); - gtk_widget_set_hexpand(search, TRUE); - gtk_grid_attach_next_to(GTK_GRID(base->widget), search, label, GTK_POS_RIGHT, 1, 1); - - /* Partie paramètres */ - - scrolled = gtk_scrolled_window_new(NULL, NULL); - gtk_widget_show(scrolled); - gtk_widget_set_vexpand(scrolled, TRUE); - gtk_grid_attach_next_to(GTK_GRID(base->widget), scrolled, label, GTK_POS_BOTTOM, 2, 1); - - 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); + /* Partie signets */ store = gtk_tree_store_new(BMC_COUNT, G_TYPE_OBJECT, CAIRO_GOBJECT_TYPE_SURFACE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); @@ -287,7 +269,7 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel) G_CALLBACK(on_key_pressed_over_params), panel); gtk_widget_show(treeview); - gtk_container_add(GTK_CONTAINER(scrolled), treeview); + gtk_container_add(GTK_CONTAINER(base->widget), treeview); g_object_unref(G_OBJECT(store)); @@ -352,6 +334,35 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel) /****************************************************************************** * * +* Paramètres : iface = interface GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de rassemblement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bookmarks_panel_dockable_interface_init(GtkDockableInterface *iface) +{ + GtkDockableInterface *parent_iface; /* Définition précédente */ + + parent_iface = (GtkDockableInterface *)g_type_interface_peek_parent(iface); + + iface->can_search = true; + iface->can_be_closed = true; + + iface->get_name = parent_iface->get_name; + iface->get_desc = parent_iface->get_desc; + iface->get_widget = parent_iface->get_widget; + iface->update_filtered = (update_filtered_data_fc)update_filtered_bookmarks; + +} + + +/****************************************************************************** +* * * Paramètres : panel = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * @@ -385,10 +396,7 @@ static void g_bookmarks_panel_dispose(GBookmarksPanel *panel) ******************************************************************************/ static void g_bookmarks_panel_finalize(GBookmarksPanel *panel) -{ - if (panel->filter != NULL) - regfree(panel->filter); - +{ G_OBJECT_CLASS(g_bookmarks_panel_parent_class)->finalize(G_OBJECT(panel)); } @@ -485,6 +493,7 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary const vmpa2t *addr; /* Adressse associée au signet */ VMPA_BUFFER(phys); /* Position physique */ VMPA_BUFFER(virt); /* Adresse virtuelle */ + const char *comment; /* Commentaire associé */ GtkTreeIter iter; /* Point d'insertion */ /* Basculement du binaire utilisé */ @@ -537,13 +546,18 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary vmpa2_phys_to_string(addr, msize, phys, NULL); vmpa2_virt_to_string(addr, msize, virt, NULL); + comment = g_db_bookmark_get_comment(bookmark); + + if (is_bookmark_filtered(panel, phys, virt, comment)) + continue; + gtk_tree_store_append(store, &iter, NULL); gtk_tree_store_set(store, &iter, BMC_BOOKMARK, bookmark, BMC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img, BMC_PHYSICAL, phys, BMC_VIRTUAL, virt, - BMC_COMMENT, g_db_bookmark_get_comment(bookmark), + BMC_COMMENT, comment, -1); } @@ -970,8 +984,8 @@ static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gc /****************************************************************************** * * -* Paramètres : entry = entrée de texte contenant le filtre brut. * -* panel = panneau assurant l'affichage des paramètres. * +* Paramètres : panel = panneau assurant l'affichage des paramètres. * +* preg = expression régulière compilée à utiliser. * * * * Description : Démarre l'actualisation du filtrage des paramètres. * * * @@ -981,76 +995,51 @@ static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gc * * ******************************************************************************/ -static void on_param_search_changed(GtkSearchEntry *entry, GBookmarksPanel *panel) +static void update_filtered_bookmarks(GBookmarksPanel *panel, const regex_t *preg) { - const gchar *text; /* Texte de l'utilisateur */ - int ret; /* Bilan de mise en place */ - GdkRGBA error; /* Couleur d'erreur */ - - if (panel->filter != NULL) - { - regfree(panel->filter); - free(panel->filter); - panel->filter = NULL; - } - - text = gtk_entry_get_text(GTK_ENTRY(entry)); - - if (strlen(text) > 0) - { - panel->filter = (regex_t *)calloc(1, sizeof(regex_t)); - ret = regcomp(panel->filter, text, REG_EXTENDED); - - if (ret != 0) - { - free(panel->filter); - panel->filter = NULL; + panel->filter = preg; - error.red = 1.0; - error.green = 0.0; - error.blue = 0.0; - error.alpha = 1.0; - gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error); - - return; - - } - - } - - gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL); - - //reload_config_into_treeview(panel, get_main_configuration()); + reload_bookmarks_into_treeview(panel, panel->binary); } /****************************************************************************** * * -* Paramètres : panel = panneau assurant l'affichage des paramètres. * -* name = chemin d'accès au paramètre à traiter. * +* Paramètres : panel = panneau assurant l'affichage des paramètres. * +* phys = position physique du signet. * +* virt = adresse virtuelle du signet. * +* comment = commentaire lisible associé au signet. * * * -* Description : Détermine si un paramètre doit être filtré ou non. * +* Description : Détermine si un signet doit être filtré ou non. * * * -* Retour : true si le paramètre ne doit pas être affiché, false sinon. * +* Retour : true si le signet ne doit pas être affiché, false sinon. * * * * Remarques : - * * * ******************************************************************************/ -static bool is_param_filtered(GBookmarksPanel *panel, const char *name) +static bool is_bookmark_filtered(GBookmarksPanel *panel, const char *phys, const char *virt, const char *comment) { + bool result; /* Bilan à retourner */ regmatch_t match; /* Récupération des trouvailles*/ int ret; /* Bilan du filtrage */ if (panel->filter == NULL) return false; - ret = regexec(panel->filter, name, 1, &match, 0); - if (ret == REG_NOMATCH) - return true; + result = true; + + ret = regexec(panel->filter, phys, 1, &match, 0); + result &= (ret == REG_NOMATCH); - return false; + ret = regexec(panel->filter, virt, 1, &match, 0); + result &= (ret == REG_NOMATCH); + + ret = regexec(panel->filter, comment, 1, &match, 0); + result &= (ret == REG_NOMATCH); + + return result; } diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c index 8a46025..7f18fea 100644 --- a/src/gui/panels/panel.c +++ b/src/gui/panels/panel.c @@ -40,6 +40,7 @@ #include "symbols.h" #include "welcome.h" #include "../../gtkext/easygtk.h" +#include "../../gtkext/gtkdockable-int.h" #include "../../gtkext/gtkdockstation.h" @@ -67,6 +68,18 @@ static void g_panel_item_class_init(GPanelItemClass *); /* Initialise une instance d'élément réactif pour l'éditeur. */ static void g_panel_item_init(GPanelItem *); +/* Procède à l'initialisation de l'interface de rassemblement. */ +static void g_panel_item_dockable_interface_init(GtkDockableInterface *); + +/* Fournit le nom court du composant encapsulable. */ +static const char *gtk_panel_item_get_name(const GPanelItem *); + +/* Fournit le nom long du composant encapsulable. */ +static const char *gtk_panel_item_get_desc(const GPanelItem *); + +/* Fournit le composant graphique intégrable dans un ensemble. */ +static GtkWidget *gtk_panel_item_get_widget(GPanelItem *); + /* ---------------------- MECANISMES DE PLACEMENT DES PANNEAUX ---------------------- */ @@ -129,7 +142,8 @@ static void on_docking_to_main_panel(GtkDockStation *, GtkWidget *, gpointer); /* Indique le type défini pour un élément destiné à un panneau. */ -G_DEFINE_TYPE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM); +G_DEFINE_TYPE_WITH_CODE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM, + G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_panel_item_dockable_interface_init)) /****************************************************************************** @@ -171,6 +185,31 @@ static void g_panel_item_init(GPanelItem *item) /****************************************************************************** * * +* Paramètres : iface = interface GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de rassemblement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface) +{ + iface->can_search = false; + iface->can_be_closed = true; + + iface->get_name = (get_dockable_name_fc)gtk_panel_item_get_name; + iface->get_desc = (get_dockable_desc_fc)gtk_panel_item_get_desc; + iface->get_widget = (get_dockable_widget_fc)gtk_panel_item_get_widget; + iface->update_filtered = (update_filtered_data_fc)NULL; + +} + + +/****************************************************************************** +* * * Paramètres : item = composant à présenter à l'affichage. * * ref = espace de référencement global. * * name = nom associé à l'élément. * @@ -240,6 +279,63 @@ GEditorItem *g_panel_item_new(GObject *ref, const char *name, const char *lname, /****************************************************************************** * * +* Paramètres : item = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le nom court du composant encapsulable. * +* * +* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *gtk_panel_item_get_name(const GPanelItem *item) +{ + return G_EDITOR_ITEM(item)->name; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le nom long du composant encapsulable. * +* * +* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *gtk_panel_item_get_desc(const GPanelItem *item) +{ + return item->lname; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le composant graphique intégrable dans un ensemble. * +* * +* Retour : Composant graphique prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item) +{ + return G_EDITOR_ITEM(item)->widget; + +} + + +/****************************************************************************** +* * * Paramètres : name = désignation courte servant de clef. * * * * Description : Recherche un panneau à partir de son nom court. * @@ -423,7 +519,6 @@ static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const cha { panel_node *result; /* Structure à retourner */ GtkWidget *station; /* Premier support concentré */ - GEditorItem *editem; /* Autre vision des choses */ result = (panel_node *)calloc(1, sizeof(panel_node)); @@ -438,9 +533,7 @@ static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const cha result->station = station; - editem = G_EDITOR_ITEM(item); - gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), - editem->widget, editem->name, item->lname); + gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item)); return result; @@ -695,10 +788,7 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const { /* Le parcours s'arrête ici ! */ if (strcmp(node->path, path) == 0) - gtk_dock_panel_add_widget(GTK_DOCK_STATION(node->station), - G_EDITOR_ITEM(item)->widget, - G_EDITOR_ITEM(item)->name, - item->lname); + gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item)); /* On ne peut aller plus loin, on doit diviser... */ else diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c index 8d41165..4d7d077 100644 --- a/src/gui/panels/strings.c +++ b/src/gui/panels/strings.c @@ -26,7 +26,6 @@ #include -#include #include "panel-int.h" @@ -34,6 +33,7 @@ #include "../../core/params.h" #include "../../dialogs/gotox.h" #include "../../gtkext/easygtk.h" +#include "../../gtkext/gtkdockable-int.h" @@ -46,7 +46,7 @@ struct _GStringsPanel GPanelItem parent; /* A laisser en premier */ GtkTreeView *treeview; /* Composant d'affichage */ - regex_t *filter; /* Filtre appliqué ou NULL */ + const regex_t *filter; /* Filtre appliqué ou NULL */ GtkMenu *menu; /* Menu contextuel pour param. */ @@ -84,22 +84,23 @@ static void g_strings_panel_class_init(GStringsPanelClass *); /* Initialise une instance de panneau d'affichage des chaînes. */ static void g_strings_panel_init(GStringsPanel *); +/* Procède à l'initialisation de l'interface de rassemblement. */ +static void g_strings_panel_dockable_interface_init(GtkDockableInterface *); + /* Supprime toutes les références externes. */ static void g_strings_panel_dispose(GStringsPanel *); /* Procède à la libération totale de la mémoire. */ static void g_strings_panel_finalize(GStringsPanel *); -/* Réagit à un changement d'affichage principal de contenu. */ -static void change_strings_panel_current_binary(GStringsPanel *, GLoadedBinary *); - - - /* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */ +/* Réagit à un changement d'affichage principal de contenu. */ +static void change_strings_panel_current_binary(GStringsPanel *, GLoadedBinary *); + /* Réagit au changement de sélection des chaînes textuelles. */ static void on_strings_selection_change(GtkTreeSelection *, GStringsPanel *); @@ -117,8 +118,8 @@ static void on_string_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkT /* ------------------------- FILTRAGE DES SYMBOLES PRESENTS ------------------------- */ -/* Démarre l'actualisation du filtrage des paramètres. */ -static void on_string_search_changed(GtkSearchEntry *, GStringsPanel *); +/* Démarre l'actualisation du filtrage des chaînes. */ +static void update_filtered_strings(GStringsPanel *, const regex_t *); /* Détermine si une chaîne textuelle doit être filtrée ou non. */ static bool is_string_filtered(GStringsPanel *, const char *, const char *); @@ -151,14 +152,14 @@ static void mcb_strings_panel_filter(GtkMenuItem *, GStringsPanel *); - /* ---------------------------------------------------------------------------------- */ /* PARTIE PRINCIPALE DU PANNEAU */ /* ---------------------------------------------------------------------------------- */ /* Indique le type définit pour un panneau d'affichage des chaînes. */ -G_DEFINE_TYPE(GStringsPanel, g_strings_panel, G_TYPE_PANEL_ITEM); +G_DEFINE_TYPE_WITH_CODE(GStringsPanel, g_strings_panel, G_TYPE_PANEL_ITEM, + G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_strings_panel_dockable_interface_init)) /****************************************************************************** @@ -206,9 +207,6 @@ static void g_strings_panel_init(GStringsPanel *panel) { GEditorItem *base; /* Version basique d'instance */ GObject *ref; /* Espace de référencement */ - GtkWidget *label; /* Etiquette à utiliser */ - GtkWidget *search; /* Zone de recherche */ - GtkWidget *scrolled; /* Fenêtre défilante */ GtkTreeStore *store; /* Modèle de gestion */ GtkWidget *treeview; /* Affichage de la liste */ GtkCellRenderer *renderer; /* Moteur de rendu de colonne */ @@ -219,35 +217,16 @@ static void g_strings_panel_init(GStringsPanel *panel) base = G_EDITOR_ITEM(panel); - base->widget = gtk_grid_new(); + base->widget = gtk_scrolled_window_new(NULL, NULL); gtk_widget_show(base->widget); - gtk_grid_set_row_spacing(GTK_GRID(base->widget), 8); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(base->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(base->widget), GTK_SHADOW_IN); ref = G_OBJECT(base->widget); g_object_set_data(ref, "panel", panel); - /* Partie recherche */ - - label = qck_create_label(NULL, NULL, _("Look for:")); - g_object_set(label, "margin", 8, NULL); - gtk_grid_attach(GTK_GRID(base->widget), label, 0, 0, 1, 1); - - search = gtk_search_entry_new(); - g_signal_connect(search, "search-changed", G_CALLBACK(on_string_search_changed), panel); - gtk_widget_show(search); - gtk_widget_set_hexpand(search, TRUE); - gtk_grid_attach_next_to(GTK_GRID(base->widget), search, label, GTK_POS_RIGHT, 1, 1); - - /* Partie paramètres */ - - scrolled = gtk_scrolled_window_new(NULL, NULL); - gtk_widget_show(scrolled); - gtk_widget_set_vexpand(scrolled, TRUE); - gtk_grid_attach_next_to(GTK_GRID(base->widget), scrolled, label, GTK_POS_BOTTOM, 2, 1); - - 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); + /* Partie chaînes */ store = gtk_tree_store_new(STC_COUNT, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); @@ -263,7 +242,7 @@ static void g_strings_panel_init(GStringsPanel *panel) G_CALLBACK(on_key_pressed_over_strings), panel); gtk_widget_show(treeview); - gtk_container_add(GTK_CONTAINER(scrolled), treeview); + gtk_container_add(GTK_CONTAINER(base->widget), treeview); g_object_unref(G_OBJECT(store)); @@ -336,6 +315,35 @@ static void g_strings_panel_init(GStringsPanel *panel) /****************************************************************************** * * +* Paramètres : iface = interface GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de rassemblement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_strings_panel_dockable_interface_init(GtkDockableInterface *iface) +{ + GtkDockableInterface *parent_iface; /* Définition précédente */ + + parent_iface = (GtkDockableInterface *)g_type_interface_peek_parent(iface); + + iface->can_search = true; + iface->can_be_closed = true; + + iface->get_name = parent_iface->get_name; + iface->get_desc = parent_iface->get_desc; + iface->get_widget = parent_iface->get_widget; + iface->update_filtered = (update_filtered_data_fc)update_filtered_strings; + +} + + +/****************************************************************************** +* * * Paramètres : panel = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * @@ -708,10 +716,10 @@ static void on_string_value_edited(GtkCellRendererText *renderer, gchar *path, g /****************************************************************************** * * -* Paramètres : entry = entrée de texte contenant le filtre brut. * -* panel = panneau assurant l'affichage des paramètres. * +* Paramètres : panel = panneau assurant l'affichage des paramètres. * +* preg = expression régulière compilée à utiliser. * * * -* Description : Démarre l'actualisation du filtrage des paramètres. * +* Description : Démarre l'actualisation du filtrage des chaînes. * * * * Retour : - * * * @@ -719,44 +727,9 @@ static void on_string_value_edited(GtkCellRendererText *renderer, gchar *path, g * * ******************************************************************************/ -static void on_string_search_changed(GtkSearchEntry *entry, GStringsPanel *panel) +static void update_filtered_strings(GStringsPanel *panel, const regex_t *preg) { - const gchar *text; /* Texte de l'utilisateur */ - int ret; /* Bilan de mise en place */ - GdkRGBA error; /* Couleur d'erreur */ - - if (panel->filter != NULL) - { - regfree(panel->filter); - free(panel->filter); - panel->filter = NULL; - } - - text = gtk_entry_get_text(GTK_ENTRY(entry)); - - if (strlen(text) > 0) - { - panel->filter = (regex_t *)calloc(1, sizeof(regex_t)); - ret = regcomp(panel->filter, text, REG_EXTENDED); - - if (ret != 0) - { - free(panel->filter); - panel->filter = NULL; - - error.red = 1.0; - error.green = 0.0; - error.blue = 0.0; - error.alpha = 1.0; - gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error); - - return; - - } - - } - - gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL); + panel->filter = preg; change_strings_panel_current_binary(panel, panel->binary); @@ -786,18 +759,18 @@ static bool is_string_filtered(GStringsPanel *panel, const char *label, const ch if (panel->filter == NULL) return false; - result = false; + result = true; if (label != NULL) { ret = regexec(panel->filter, label, 1, &match, 0); - result |= (ret != REG_NOMATCH); + result &= (ret == REG_NOMATCH); } ret = regexec(panel->filter, value, 1, &match, 0); - result |= (ret != REG_NOMATCH); + result &= (ret == REG_NOMATCH); - return !result; + return result; } -- cgit v0.11.2-87-g4458