From 6cbb81bc46347ce969f5bf24a73f08abd009b82b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 22 Apr 2015 00:11:29 +0000
Subject: Allowed to refer to an external list for highlighted segments.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@515 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                  | 22 ++++++++++++++++++++++
 src/dialogs/export.c       |  2 +-
 src/glibext/gcodebuffer.c  | 15 +++++++++++----
 src/glibext/gcodebuffer.h  |  2 +-
 src/gtkext/gtkblockview.c  | 25 ++++++++++++++++++++++---
 src/gtkext/gtkbufferview.c |  1 +
 src/gtkext/gtkgraphview.c  | 41 ++++++++++++++++++++++++++++++++++++++++-
 src/gtkext/gtksourceview.c |  2 +-
 8 files changed, 99 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4ace600..c1874c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+15-04-22  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/dialogs/export.c:
+	Update call to g_buffer_view_new().
+
+	* src/glibext/gcodebuffer.c:
+	* src/glibext/gcodebuffer.h:
+	Allow to refer to an external list for highlighted segments.
+
+	* src/gtkext/gtkblockview.c:
+	Send a signal when segments get [un]selected. Update call to
+	g_buffer_view_new().
+
+	* src/gtkext/gtkbufferview.c:
+	Do not draw a background for the selected line when a widget loses its focus.
+
+	* src/gtkext/gtkgraphview.c:
+	Update code.
+
+	* src/gtkext/gtksourceview.c:
+	Update call to g_buffer_view_new().
+
 15-04-21  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/arch/processor.c:
diff --git a/src/dialogs/export.c b/src/dialogs/export.c
index 5667730..16622a9 100644
--- a/src/dialogs/export.c
+++ b/src/dialogs/export.c
@@ -259,7 +259,7 @@ static void export_assistant_close(GtkAssistant *assistant, GObject *ref)
     binary = G_LOADED_BINARY(g_object_get_data(ref, "binary"));
 
     buffer = g_loaded_binary_get_disassembled_buffer(binary);
-    view = g_buffer_view_new(buffer);
+    view = g_buffer_view_new(buffer, NULL);
 
     g_buffer_view_export(view, &ctx, type, display);
 
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index a7e522c..8633461 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -156,6 +156,7 @@ struct _GBufferView
     BufferLineColumn last_merge;            /* Colonne de fusion extrême   */
 
     segcnt_list *highlighted;               /* Segments mis en évidence    */
+    bool external;                          /* Note l'origine de la liste  */
 
 };
 
@@ -917,8 +918,6 @@ static void g_buffer_view_init(GBufferView *buffer)
     g_buffer_view_reset_required_height(buffer);
     g_buffer_view_reset_required_widths(buffer);
 
-    buffer->highlighted = init_segment_content_list();
-
 }
 
 
@@ -955,7 +954,8 @@ static void g_buffer_view_dispose(GBufferView *view)
 
 static void g_buffer_view_finalize(GBufferView *view)
 {
-    exit_segment_content_list(view->highlighted);
+    if (!view->external)
+        exit_segment_content_list(view->highlighted);
 
     G_OBJECT_CLASS(g_buffer_view_parent_class)->finalize(G_OBJECT(view));
 
@@ -975,7 +975,7 @@ static void g_buffer_view_finalize(GBufferView *view)
 *                                                                             *
 ******************************************************************************/
 
-GBufferView *g_buffer_view_new(GCodeBuffer *buffer)
+GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
 {
     GBufferView *result;                    /* Composant à retourner       */
 
@@ -987,6 +987,13 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer)
 
     g_buffer_view_restrict(result, NULL, NULL);
 
+    if (highlighted != NULL)
+        result->highlighted = highlighted;
+    else
+        result->highlighted = init_segment_content_list();
+
+    result->external = (highlighted != NULL);
+
     return result;
 
 }
diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h
index 846da64..a248df3 100644
--- a/src/glibext/gcodebuffer.h
+++ b/src/glibext/gcodebuffer.h
@@ -108,7 +108,7 @@ typedef struct _GBufferViewClass GBufferViewClass;
 GType g_buffer_view_get_type(void);
 
 /* Crée une nouvelle vue d'un tampon pour code désassemblé. */
-GBufferView *g_buffer_view_new(GCodeBuffer *);
+GBufferView *g_buffer_view_new(GCodeBuffer *, segcnt_list *);
 
 /* Restreint le champ d'application de l'affichage. */
 void g_buffer_view_restrict(GBufferView *, const vmpa2t *, const vmpa2t *);
diff --git a/src/gtkext/gtkblockview.c b/src/gtkext/gtkblockview.c
index 1c7ba43..2b72ff4 100644
--- a/src/gtkext/gtkblockview.c
+++ b/src/gtkext/gtkblockview.c
@@ -43,6 +43,10 @@ struct _GtkBlockViewClass
 {
     GtkBufferViewClass parent;              /* A laisser en premier        */
 
+    /* Signaux */
+
+    void (* highlight_changed) (GtkBlockView *);
+
 };
 
 
@@ -99,6 +103,14 @@ static void gtk_block_view_class_init(GtkBlockViewClass *class)
 
     buffer_class->notify_caret = (notify_caret_relocation_fc)gtk_block_view_notify_caret_relocation;
 
+    g_signal_new("highlight-changed",
+                 GTK_TYPE_BLOCK_VIEW,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GtkBlockViewClass, highlight_changed),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__VOID,
+                 G_TYPE_NONE, 0);
+
 }
 
 
@@ -143,8 +155,15 @@ static void gtk_block_view_init(GtkBlockView *view)
 
 static bool gtk_block_view_notify_caret_relocation(GtkBlockView *view, const GdkRectangle *area, const vmpa2t *addr)
 {
-    return g_buffer_view_highlight_segments(GTK_BUFFER_VIEW(view)->buffer_view, area->x, area->y,
-                                            GTK_VIEW_PANEL(view)->display);
+    bool result;                            /* Bilan à retourner           */
+
+    result = g_buffer_view_highlight_segments(GTK_BUFFER_VIEW(view)->buffer_view, area->x, area->y,
+                                              GTK_VIEW_PANEL(view)->display);
+
+    if (result)
+        g_signal_emit_by_name(view, "highlight-changed");
+
+    return result;
 
 }
 
@@ -260,7 +279,7 @@ static void gtk_block_view_attach_binary(GtkBlockView *view, GLoadedBinary *bina
     GBufferView *bview;                     /* Vue sur ce même tampon      */
 
     buffer = g_loaded_binary_get_disassembled_buffer(binary);
-    bview = g_buffer_view_new(buffer);
+    bview = g_buffer_view_new(buffer, NULL);
 
     gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), bview);
 
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index 54c521e..f54ecff 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -423,6 +423,7 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr)
         gtk_buffer_view_compute_fake_coord(view, &fake_x, &fake_y);
 
         g_generic_config_get_value(get_main_configuration(), MPK_SELECTION_LINE, &sel_line);
+        sel_line &= gtk_widget_has_focus(widget);
 
         if (!sel_line || view->caret_addr == NULL)
             selected = NULL;
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index 6d7ab0d..e0eb870 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -46,6 +46,7 @@ struct _GtkGraphView
     vmpa_t start;                           /* Début de la portion vue     */ /* FIXME : à garder ? */
     vmpa_t end;                             /* Fin de la portion affichée  */ /* FIXME : à garder ? */
 
+    segcnt_list *highlighted;               /* Segments mis en évidence    */
     GtkBufferView **children;               /* Liste des sous-blocs        */
     GtkAllocation *allocs;                  /* Emplacements prévisibles    */
     size_t children_count;                  /* Taille de cette liste       */
@@ -99,6 +100,9 @@ static void gtk_graph_view_reset(GtkGraphView *);
 /* Définit la liste complète des éléments du futur graphique. */
 static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *, GLoadedBinary *, const GBinRoutine *);
 
+/* Notifie un changement de surbrillance au sein d'un noeud. */
+static void gtk_graph_view_changed_highlights(GtkBlockView *, GtkGraphView *);
+
 /* Notifie une incapacité de déplacement au sein d'un noeud. */
 static void gtk_graph_view_reach_caret_limit(GtkBufferView *, GdkScrollDirection, GtkGraphView *);
 
@@ -348,6 +352,8 @@ static void gtk_graph_view_define_main_address(GtkGraphView *view, const vmpa2t
                 view->routine = routines[i];
                 g_object_ref(G_OBJECT(view->routine));
 
+                view->highlighted = init_segment_content_list();
+
                 view->children = gtk_graph_view_load_nodes(view, GTK_VIEW_PANEL(view)->binary,
                                                            routines[i]);
 
@@ -557,6 +563,9 @@ static void gtk_graph_view_reset(GtkGraphView *view)
     }
     */
 
+    if (view->highlighted)
+        exit_segment_content_list(view->highlighted);
+
     for (i = 0; i < view->children_count; i++)
     {
         g_signal_handlers_disconnect_by_func(view->children[i], gtk_graph_view_reach_caret_limit, view);
@@ -618,6 +627,7 @@ static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBina
     {
         result[i] = GTK_VIEW_PANEL(gtk_block_view_new());
         g_signal_connect(result[i], "reach-limit", G_CALLBACK(gtk_graph_view_reach_caret_limit), view);
+        g_signal_connect(result[i], "highlight-changed", G_CALLBACK(gtk_graph_view_changed_highlights), view);
 
         gtk_widget_show(GTK_WIDGET(result[i]));
         gtk_view_panel_attach_binary(result[i], binary, BVW_BLOCK);
@@ -626,7 +636,7 @@ static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBina
 
         g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(blocks[i]), &first, &last);
 
-        subview = g_buffer_view_new(buffer);
+        subview = g_buffer_view_new(buffer, view->highlighted);
         g_buffer_view_restrict(subview, &first, &last);
         gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[i]), subview);
 
@@ -640,6 +650,35 @@ static GtkBufferView **gtk_graph_view_load_nodes(GtkGraphView *view, GLoadedBina
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : node = composant d'affichage GTK impliqué dans la procédure. *
+*                view = support graphique de tous les noeuds.                 *
+*                                                                             *
+*  Description : Notifie un changement de surbrillance au sein d'un noeud.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_graph_view_changed_highlights(GtkBlockView *node, GtkGraphView *view)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < view->children_count; i++)
+    {
+        if (view->children[i] == node)
+            continue;
+
+        gtk_widget_queue_draw(GTK_WIDGET(view->children[i]));
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = composant d'affichage GTK impliqué dans la procédure. *
 *                dir  = direction du déplacement souhaité et impossible.      *
 *                view = support graphique de tous les noeuds.                 *
 *                                                                             *
diff --git a/src/gtkext/gtksourceview.c b/src/gtkext/gtksourceview.c
index 113b9bb..254f798 100644
--- a/src/gtkext/gtksourceview.c
+++ b/src/gtkext/gtksourceview.c
@@ -151,6 +151,6 @@ static void gtk_source_view_attach_binary(GtkSourceView *view, GLoadedBinary *bi
 
     /* Si une source existe... */
     if (buffer != NULL)
-        gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), g_buffer_view_new(buffer));
+        gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(view), g_buffer_view_new(buffer, NULL));
 
 }
-- 
cgit v0.11.2-87-g4458