summaryrefslogtreecommitdiff
path: root/src/gtkext/gtkdockable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext/gtkdockable.c')
-rw-r--r--src/gtkext/gtkdockable.c381
1 files changed, 381 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "gtkdockable.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+
+
+#include <i18n.h>
+
+
+#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);
+
+}