diff options
Diffstat (limited to 'src/gtkext/gtkdockable.c')
-rw-r--r-- | src/gtkext/gtkdockable.c | 381 |
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); + +} |