[dia] property: don't use GtkList for list property



commit 91bb1179e563582caf1f3324bb33148fdded40af
Author: Zander Brown <zbrown gnome org>
Date:   Mon Dec 9 11:15:47 2019 +0000

    property: don't use GtkList for list property
    
    Make a new GtkTreeView based widget that implements just enough to replace GtkList

 lib/dia-simple-list.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/dia-simple-list.h |  48 +++++++++++++
 lib/meson.build       |   2 +
 lib/prop_widgets.c    | 118 +++++++++++++++---------------
 lib/prop_widgets.h    |   1 -
 5 files changed, 302 insertions(+), 62 deletions(-)
---
diff --git a/lib/dia-simple-list.c b/lib/dia-simple-list.c
new file mode 100644
index 00000000..da4e0b89
--- /dev/null
+++ b/lib/dia-simple-list.c
@@ -0,0 +1,195 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2019 Zander Brown <zbrown gnome org>
+ */
+
+#include <config.h>
+#include "intl.h"
+#include <gtk/gtk.h>
+#include "dia-simple-list.h"
+
+
+typedef struct _DiaSimpleListPrivate DiaSimpleListPrivate;
+struct _DiaSimpleListPrivate {
+  GtkListStore     *store;
+  GtkTreeSelection *selection;
+};
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (DiaSimpleList, dia_simple_list, GTK_TYPE_TREE_VIEW)
+
+
+enum {
+  SELECTION_CHANGED,
+  LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = { 0, };
+
+
+static void
+dia_simple_list_finalize (GObject *object)
+{
+  DiaSimpleList *self = DIA_SIMPLE_LIST (object);
+  DiaSimpleListPrivate *priv = dia_simple_list_get_instance_private (self);
+
+  g_clear_object (&priv->store);
+
+  G_OBJECT_CLASS (dia_simple_list_parent_class)->finalize (object);
+}
+
+
+static void
+dia_simple_list_class_init (DiaSimpleListClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = dia_simple_list_finalize;
+
+  signals[SELECTION_CHANGED] = g_signal_new ("selection-changed",
+                                             G_TYPE_FROM_CLASS (klass),
+                                             G_SIGNAL_RUN_FIRST,
+                                             0,
+                                             NULL, NULL, NULL,
+                                             G_TYPE_NONE,
+                                             0);
+}
+
+
+static void
+selection_changed (GtkTreeSelection *treeselection,
+                   DiaSimpleList    *self)
+{
+  g_signal_emit (self, signals[SELECTION_CHANGED], 0);
+}
+
+
+static void
+dia_simple_list_init (DiaSimpleList *self)
+{
+  DiaSimpleListPrivate *priv = dia_simple_list_get_instance_private (self);
+
+  priv->store = gtk_list_store_new (1, G_TYPE_STRING);
+
+  gtk_tree_view_set_model (GTK_TREE_VIEW (self), GTK_TREE_MODEL (priv->store));
+
+  priv->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+
+  gtk_tree_selection_unselect_all (priv->selection);
+  gtk_tree_selection_set_mode (priv->selection,
+                               GTK_SELECTION_BROWSE);
+
+  g_signal_connect (priv->selection,
+                    "changed",
+                    G_CALLBACK (selection_changed),
+                    self);
+}
+
+
+GtkWidget *
+dia_simple_list_new (void)
+{
+  return g_object_new (DIA_TYPE_SIMPLE_LIST, NULL);
+}
+
+
+void
+dia_simple_list_empty (DiaSimpleList *self)
+{
+  DiaSimpleListPrivate *priv;
+
+  g_return_if_fail (DIA_IS_SIMPLE_LIST (self));
+
+  priv = dia_simple_list_get_instance_private (self);
+
+  gtk_list_store_clear (priv->store);
+}
+
+
+void
+dia_simple_list_append (DiaSimpleList *self,
+                        const char    *item)
+{
+  DiaSimpleListPrivate *priv;
+  GtkTreeIter iter;
+
+  g_return_if_fail (DIA_IS_SIMPLE_LIST (self));
+
+  priv = dia_simple_list_get_instance_private (self);
+
+  gtk_list_store_append (priv->store, &iter);
+  gtk_list_store_set (priv->store, &iter, 0, item, -1);
+}
+
+
+void
+dia_simple_list_select (DiaSimpleList *self,
+                        int            n)
+{
+  DiaSimpleListPrivate *priv;
+  GtkTreeIter iter;
+
+  g_return_if_fail (DIA_IS_SIMPLE_LIST (self));
+
+  priv = dia_simple_list_get_instance_private (self);
+
+  if (n == -1) {
+    gtk_tree_selection_unselect_all (priv->selection);
+    return;
+  }
+
+  if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (priv->store),
+                                      &iter,
+                                      NULL,
+                                      n)) {
+    g_warning ("Can't select %i", n);
+    return;
+  }
+
+  gtk_tree_selection_select_iter (priv->selection, &iter);
+}
+
+
+int
+dia_simple_list_get_selected (DiaSimpleList *self)
+{
+  DiaSimpleListPrivate *priv;
+  GtkTreeIter iter;
+  GtkTreePath *path;
+  int res;
+
+  g_return_val_if_fail (DIA_IS_SIMPLE_LIST (self), -1);
+
+  priv = dia_simple_list_get_instance_private (self);
+
+  if (!gtk_tree_selection_get_selected (priv->selection, NULL, &iter)) {
+    return -1;
+  }
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (self), &iter);
+
+  g_return_val_if_fail (gtk_tree_path_get_depth (path) == 1, -1);
+
+  res = gtk_tree_path_get_indices (path)[0];
+
+  gtk_tree_path_free (path);
+
+  return res;
+}
+
diff --git a/lib/dia-simple-list.h b/lib/dia-simple-list.h
new file mode 100644
index 00000000..33b989f4
--- /dev/null
+++ b/lib/dia-simple-list.h
@@ -0,0 +1,48 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright © 2019 Zander Brown <zbrown gnome org>
+ */
+
+#include <gtk/gtk.h>
+
+#pragma once
+
+G_BEGIN_DECLS
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (GtkTreeView, g_object_unref)
+
+#define DIA_TYPE_SIMPLE_LIST dia_simple_list_get_type ()
+G_DECLARE_DERIVABLE_TYPE (DiaSimpleList, dia_simple_list, DIA, SIMPLE_LIST, GtkTreeView)
+
+struct _DiaSimpleListClass {
+  GtkTreeViewClass parent_class;
+};
+
+
+GtkWidget *dia_simple_list_new          (void);
+void       dia_simple_list_empty        (DiaSimpleList *self);
+void       dia_simple_list_append       (DiaSimpleList *self,
+                                         const char    *item);
+void       dia_simple_list_select       (DiaSimpleList *self,
+                                         int            n);
+int        dia_simple_list_get_selected (DiaSimpleList *self);
+
+
+G_END_DECLS
diff --git a/lib/meson.build b/lib/meson.build
index 56383770..0e2eda5d 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -157,6 +157,8 @@ libdia_sources = stdprop_sources + [
     'dia-colour-cell-renderer.h',
     'dia-line-cell-renderer.c',
     'dia-line-cell-renderer.h',
+    'dia-simple-list.c',
+    'dia-simple-list.h',
 ]
 
 gnome = import('gnome')
diff --git a/lib/prop_widgets.c b/lib/prop_widgets.c
index 71b5dd9c..906e977a 100644
--- a/lib/prop_widgets.c
+++ b/lib/prop_widgets.c
@@ -25,12 +25,12 @@
 #include <config.h>
 
 #include <glib.h>
-#undef GTK_DISABLE_DEPRECATED /* GtkList */
 #include <gtk/gtk.h>
 #define WIDGET GtkWidget
 #include "widgets.h"
 #include "properties.h"
 #include "propinternals.h"
+#include "dia-simple-list.h"
 
 /******************************/
 /* The STATIC property type.  */
@@ -387,123 +387,119 @@ static const PropertyOps notebook_endprop_ops = {
 /****************************/
 
 static void
-listprop_emptylines_realloc(ListProperty *prop,guint new_size) {
+listprop_emptylines_realloc (ListProperty *prop, guint new_size) {
   guint i;
 
-  for (i = 0; i < prop->lines->len; i++)
-    g_free(g_ptr_array_index(prop->lines,i));
-  g_ptr_array_set_size(prop->lines,new_size);
+  for (i = 0; i < prop->lines->len; i++) {
+    g_free (g_ptr_array_index (prop->lines, i));
+  }
+  g_ptr_array_set_size (prop->lines,new_size);
 }
 
+
 static void
-listprop_copylines(ListProperty *prop, GPtrArray *src) {
+listprop_copylines (ListProperty *prop, GPtrArray *src) {
   guint i;
 
-  listprop_emptylines_realloc(prop,src->len);
+  listprop_emptylines_realloc (prop, src->len);
 
-  for (i = 0; i < src->len; i++)
-    g_ptr_array_index(prop->lines,i) = g_strdup(g_ptr_array_index(src,i));
+  for (i = 0; i < src->len; i++) {
+    g_ptr_array_index (prop->lines, i) = g_strdup (g_ptr_array_index (src, i));
+  }
 }
 
+
 static ListProperty *
-listprop_new(const PropDescription *pdesc, PropDescToPropPredicate reason)
+listprop_new (const PropDescription *pdesc, PropDescToPropPredicate reason)
 {
-  ListProperty *prop = g_new0(ListProperty,1);
-  initialize_property(&prop->common,pdesc,reason);
+  ListProperty *prop = g_new0 (ListProperty,1);
+  initialize_property (&prop->common, pdesc, reason);
   prop->selected = -1;
-  prop->w_selected = -1;
-  prop->lines = g_ptr_array_new();
+  prop->lines = g_ptr_array_new ();
   return prop;
 }
 
+
 static void
-listprop_free(ListProperty *prop)
+listprop_free (ListProperty *prop)
 {
-  listprop_emptylines_realloc(prop,-1);
-  g_ptr_array_free(prop->lines,TRUE);
+  listprop_emptylines_realloc (prop,-1);
+  g_ptr_array_free (prop->lines,TRUE);
 }
 
+
 static ListProperty *
-listprop_copy(ListProperty *src)
+listprop_copy (ListProperty *src)
 {
   ListProperty *prop =
-    (ListProperty *)src->common.ops->new_prop(src->common.descr,
-                                               src->common.reason);
+    (ListProperty *) src->common.ops->new_prop (src->common.descr,
+                                                src->common.reason);
 
-  copy_init_property(&prop->common,&src->common);
+  copy_init_property (&prop->common,&src->common);
   prop->selected = src->selected;
-  prop->w_selected = src->w_selected;
-  listprop_copylines(prop,src->lines);
+  listprop_copylines (prop,src->lines);
 
   return prop;
 }
 
-static void
-listprop_select_child_signal(GtkList *list,
-                             GtkWidget *child,
-                             ListProperty *prop)
-{
-  prop->w_selected = gtk_list_child_position(list,child);
-}
 
-static WIDGET *
-listprop_get_widget(ListProperty *prop, PropDialog *dialog)
+static GtkWidget *
+listprop_get_widget (ListProperty *prop, PropDialog *dialog)
 {
-  GtkWidget *ret = gtk_list_new();
-
-  gtk_list_set_selection_mode(GTK_LIST(ret),GTK_SELECTION_BROWSE);
-  gtk_list_unselect_all(GTK_LIST(ret));
+  GtkWidget *ret = dia_simple_list_new ();
 
-  g_signal_connect(G_OBJECT(ret), "select-child",
-                   G_CALLBACK (listprop_select_child_signal), prop);
+  prophandler_connect (&prop->common, G_OBJECT(ret), "selection-changed");
 
-  prophandler_connect(&prop->common, G_OBJECT(ret), "selection-changed");
   return ret;
 }
 
-static GtkWidget *
-make_item(const gchar *line) {
-  GtkWidget *item = gtk_list_item_new_with_label(line);
-  gtk_widget_show(item);
-  return item;
-}
 
 static void
-listprop_reset_widget(ListProperty *prop, WIDGET *widget)
+listprop_reset_widget (ListProperty *prop, GtkWidget *widget)
 {
   guint i;
-  GList *items = NULL;
-  gtk_list_clear_items(GTK_LIST(widget),0,-1);
+
+  g_return_if_fail (DIA_IS_SIMPLE_LIST (widget));
+
+  dia_simple_list_empty (DIA_SIMPLE_LIST (widget));
 
   for (i = 0; i < prop->lines->len; i++) {
-    items = g_list_append(items, make_item(g_ptr_array_index(prop->lines,i)));
+    dia_simple_list_append (DIA_SIMPLE_LIST (widget),
+                            g_ptr_array_index (prop->lines, i));
   }
-  gtk_list_append_items(GTK_LIST(widget),items);
-  prop->w_selected = prop->selected;
-  gtk_list_select_item(GTK_LIST(widget),prop->selected);
+
+  dia_simple_list_select (DIA_SIMPLE_LIST (widget), prop->selected);
 }
 
+
 static void
-listprop_set_from_widget(ListProperty *prop, WIDGET *widget)
+listprop_set_from_widget (ListProperty *prop, WIDGET *widget)
 {
-  prop->selected = prop->w_selected;
+  prop->selected = dia_simple_list_get_selected (DIA_SIMPLE_LIST (widget));
 }
 
+
 static void
-listprop_get_from_offset(ListProperty *prop,
-                         void *base, guint offset, guint offset2)
+listprop_get_from_offset (ListProperty *prop,
+                          void         *base,
+                          guint         offset,
+                          guint         offset2)
 {
-  listprop_copylines(prop,struct_member(base,offset, GPtrArray *));
-  prop->selected = struct_member(base,offset2,gint);
+  listprop_copylines (prop, struct_member (base,offset, GPtrArray *));
+  prop->selected = struct_member (base,offset2,gint);
 }
 
+
 static void
-listprop_set_from_offset(ListProperty *prop,
-                         void *base, guint offset, guint offset2)
+listprop_set_from_offset (ListProperty *prop,
+                          void         *base,
+                          guint         offset,
+                          guint         offset2)
 {
-  struct_member(base,offset2,gint) = prop->selected;
+  struct_member (base, offset2, gint) = prop->selected;
 }
 
+
 static const PropertyOps listprop_ops = {
   (PropertyType_New) listprop_new,
   (PropertyType_Free) listprop_free,
diff --git a/lib/prop_widgets.h b/lib/prop_widgets.h
index 1bb775af..ed7cdad1 100644
--- a/lib/prop_widgets.h
+++ b/lib/prop_widgets.h
@@ -56,7 +56,6 @@ typedef struct {
   Property common;
   gint selected;
   GPtrArray *lines;
-  gint w_selected;
 } ListProperty;
 
 void prop_widgets_register(void);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]