summaryrefslogtreecommitdiff
path: root/lib/diacellrendererenum.c
blob: 7f2ae1ac0750ae49bd7b3cdeb40f47d8a39bf7ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <config.h>

#include "diacellrendererenum.h"
#include "properties.h"

enum
{
  COLUMN_ENUM_NAME,
  COLUMN_ENUM_VALUE,
  NUM_ENUM_COLUMNS
};

/*!
 * \brief Signal handler GtkCellRendererCombo::changed:
 *
 * From GTK+:
 *
 * @renderer: the object on which the signal is emitted
 * @path_string: a string of the path identifying the edited cell
 *               (relative to the tree view model)
 * @iter: the new iter selected in the combo box
 *            (relative to the combo box model)
 *
 * This signal is emitted each time after the user selected an item in
 * the combo box, either by using the mouse or the arrow keys.  Contrary
 * to GtkComboBox, GtkCellRendererCombo::changed is not emitted for
 * changes made to a selected item in the entry.  The argument 'iter'
 * corresponds to the newly selected item in the combo box and it is relative
 * to the GtkTreeModel set via the model property on GtkCellRendererCombo.
 *
 * Note that as soon as you change the model displayed in the tree view,
 * the tree view will immediately cease the editing operating.  This
 * means that you most probably want to refrain from changing the model
 * until the combo cell renderer emits the edited or editing_canceled signal.
 */
static void
_enum_changed (GtkCellRenderer *renderer,
	       const char      *path_string,
	       GtkTreeIter     *iter,
	       GtkTreeView     *tree_view)
{
  GtkTreeModel *store = gtk_tree_view_get_model (tree_view);
  int val, column;
  GtkTreeModel *model;
  GtkTreeIter store_iter;

  g_object_get (G_OBJECT (renderer), "model", &model, NULL);
  /* read the enum value from the combobox model */
  gtk_tree_model_get (model, iter, COLUMN_ENUM_VALUE, &val, -1);
  /* put it into the store model */
  column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer), COLUMN_KEY));
  if (gtk_tree_model_get_iter_from_string (store, &store_iter, path_string))
      gtk_tree_store_set (GTK_TREE_STORE (store), &store_iter, column, val, -1);

  g_print ("changed: %d - %s\n", val, path_string);
}
/*!
 * \brief Signal handler GtkCellRendererText::edited
 '
 * From GTK+:
 * This signal is emitted after @renderer has been edited.
 *
 * It is the responsibility of the application to update the model
 * and store @new_text at the position indicated by @path.
 */
static void
_enum_edited (GtkCellRenderer *renderer,
	      const char      *path_string,
	      const char      *new_string,
	      GtkTreeView     *tree_view)
{
  GtkTreeModel *store = gtk_tree_view_get_model (tree_view);
  /* Despite the comment for _enum_changed we have changed the model already
   * there. Changing it here would involve some caching of the value there
   * or translating new_string back to the enumv we need for the store.
   * But we have to mark the store to be modified otherwise only the UI state
   * would change without transferring back in _arrayprop_set_from_widget()
   */
  g_object_set_data (G_OBJECT (store), "modified", GINT_TO_POINTER (1));

  g_print ("edited: %d - %s\n", new_string);
}

GtkCellRenderer *
dia_cell_renderer_enum_new (const PropEnumData *enum_data, GtkTreeView *tree_view)
{
  /* The combo-renderer should be customized for better rendering,
   * e.g. using a shorter name like visible_char[]={ '+', '-', '#', ' ' } instead of
   * the full of _uml_visibilities[]; likewise for line style there or arrows there
   * should be a pixbuf preview instead of strings ...
   */
  GtkCellRenderer *cell_renderer = gtk_cell_renderer_combo_new ();
  /* create the model from enum_data */
  GtkListStore *model;
  GtkTreeIter iter;
  int i;
  
  model = gtk_list_store_new (NUM_ENUM_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
  for (i = 0; enum_data[i].name != NULL; ++i) {
  
    gtk_list_store_append (model, &iter);

    gtk_list_store_set (model, &iter,
                        COLUMN_ENUM_NAME, enum_data[i].name,
                        COLUMN_ENUM_VALUE, enum_data[i].enumv,
                        -1);
  }

  g_object_set (cell_renderer,
                "model", model,
                "text-column", COLUMN_ENUM_NAME,
                "has-entry", FALSE,
                "editable", TRUE,
                NULL);

  g_signal_connect (G_OBJECT (cell_renderer), "changed",
		    G_CALLBACK (_enum_changed), tree_view);
  g_signal_connect (G_OBJECT (cell_renderer), "edited",
		    G_CALLBACK (_enum_edited), tree_view);

  return cell_renderer;
}