libyui-gtk-pkg  2.42.9
 All Classes
ygtktreemodel.cc
1 /********************************************************************
2  * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
3  ********************************************************************/
4 
5 /* YGtkTreeModel, C++ wrapper for gtk+ */
6 // check the header file for information about this wrapper
7 
8 #include <gtk/gtk.h>
9 #include "ygtktreemodel.h"
10 
11 #define YGTK_TYPE_WRAP_MODEL (ygtk_wrap_model_get_type ())
12 #define YGTK_WRAP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
13  YGTK_TYPE_WRAP_MODEL, YGtkWrapModel))
14 #define YGTK_WRAP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
15  YGTK_TYPE_WRAP_MODEL, YGtkWrapModelClass))
16 #define YGTK_IS_WRAP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), YGTK_TYPE_WRAP_MODEL))
17 #define YGTK_IS_WRAP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), YGTK_TYPE_WRAP_MODEL))
18 #define YGTK_WRAP_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
19  YGTK_TYPE_WRAP_MODEL, YGtkWrapModelClass))
20 
22 {
23  GObject parent;
24  YGtkTreeModel *model;
25  struct Notify;
26  Notify *notify;
27 };
28 
30 {
31  GObjectClass parent_class;
32 };
33 
34 // bridge as we don't want to mix c++ class polymorphism and gobject
35 static void ygtk_wrap_model_entry_changed (YGtkWrapModel *model, int row);
36 static void ygtk_wrap_model_entry_inserted (YGtkWrapModel *model, int row);
37 static void ygtk_wrap_model_entry_deleted (YGtkWrapModel *model, int row);
38 
40 YGtkWrapModel *model;
41  Notify (YGtkWrapModel *model) : model (model) {}
42  virtual void rowChanged (int row)
43  { ygtk_wrap_model_entry_changed (model, row); }
44  virtual void rowInserted (int row)
45  { ygtk_wrap_model_entry_inserted (model, row); }
46  virtual void rowDeleted (int row)
47  { ygtk_wrap_model_entry_deleted (model, row); }
48 };
49 
50 static void ygtk_wrap_model_tree_model_init (GtkTreeModelIface *iface);
51 
52 G_DEFINE_TYPE_WITH_CODE (YGtkWrapModel, ygtk_wrap_model, G_TYPE_OBJECT,
53  G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, ygtk_wrap_model_tree_model_init))
54 
55 static void ygtk_wrap_model_init (YGtkWrapModel *zmodel)
56 {}
57 
58 static void ygtk_wrap_model_finalize (GObject *object)
59 {
60  YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (object);
61  delete ymodel->model;
62  ymodel->model = NULL;
63  delete ymodel->notify;
64  ymodel->notify = NULL;
65  G_OBJECT_CLASS (ygtk_wrap_model_parent_class)->finalize (object);
66 }
67 
68 static GtkTreeModelFlags ygtk_wrap_model_get_flags (GtkTreeModel *model)
69 { return (GtkTreeModelFlags) (GTK_TREE_MODEL_ITERS_PERSIST|GTK_TREE_MODEL_LIST_ONLY); }
70 
71 static gboolean ygtk_wrap_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter,
72  GtkTreePath *path)
73 { // from Path to Iter
74  YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
75  gint index = gtk_tree_path_get_indices (path)[0];
76  iter->user_data = GINT_TO_POINTER (index);
77  int rowsNb = ymodel->model->rowsNb();
78  if (!rowsNb && index == 0 && ymodel->model->showEmptyEntry())
79  return TRUE;
80  return index < rowsNb;
81 }
82 
83 static GtkTreePath *ygtk_wrap_model_get_path (GtkTreeModel *model, GtkTreeIter *iter)
84 { // from Iter to Path
85  int index = GPOINTER_TO_INT (iter->user_data);
86  GtkTreePath *path = gtk_tree_path_new();
87  gtk_tree_path_append_index (path, index);
88  return path;
89 }
90 
91 static gboolean ygtk_wrap_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter)
92 {
93  YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
94  int index = GPOINTER_TO_INT (iter->user_data) + 1;
95  iter->user_data = GINT_TO_POINTER (index);
96  int rowsNb = ymodel->model->rowsNb();
97  return index < rowsNb;
98 }
99 
100 static gboolean ygtk_wrap_model_iter_parent (GtkTreeModel *, GtkTreeIter *, GtkTreeIter *)
101 { return FALSE; }
102 
103 static gboolean ygtk_wrap_model_iter_has_child (GtkTreeModel *, GtkTreeIter *)
104 { return FALSE; }
105 
106 static gint ygtk_wrap_model_iter_n_children (GtkTreeModel *model, GtkTreeIter *iter)
107 { return 0; }
108 
109 static gboolean ygtk_wrap_model_iter_nth_child (GtkTreeModel *model, GtkTreeIter *iter,
110  GtkTreeIter *parent, gint index)
111 {
112  if (parent) return FALSE;
113  YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
114  iter->user_data = GINT_TO_POINTER (index);
115  int rowsNb = ymodel->model->rowsNb();
116  if (!rowsNb && index == 0 && ymodel->model->showEmptyEntry())
117  return TRUE;
118  return index < rowsNb;
119 }
120 
121 static gboolean ygtk_wrap_model_iter_children (
122  GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent)
123 { return ygtk_wrap_model_iter_nth_child (model, iter, parent, 0); }
124 
125 void ygtk_wrap_model_entry_changed (YGtkWrapModel *model, int row)
126 {
127  GtkTreeIter iter;
128  iter.user_data = GINT_TO_POINTER (row);
129  GtkTreePath *path = ygtk_wrap_model_get_path (GTK_TREE_MODEL (model), &iter);
130  gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
131  gtk_tree_path_free (path);
132 }
133 
134 void ygtk_wrap_model_entry_inserted (YGtkWrapModel *ymodel, int row)
135 {
136  GtkTreeModel *model = GTK_TREE_MODEL (ymodel);
137  GtkTreeIter iter;
138  iter.user_data = GINT_TO_POINTER (row);
139  GtkTreePath *path = ygtk_wrap_model_get_path (model, &iter);
140 
141  if (row == 0 && ymodel->model->rowsNb() == 1 && ymodel->model->showEmptyEntry())
142  gtk_tree_model_row_changed (model, path, &iter);
143  else
144  gtk_tree_model_row_inserted (model, path, &iter);
145  gtk_tree_path_free (path);
146 }
147 
148 void ygtk_wrap_model_entry_deleted (YGtkWrapModel *ymodel, int row)
149 {
150  GtkTreeModel *model = GTK_TREE_MODEL (ymodel);
151  GtkTreeIter iter;
152  iter.user_data = GINT_TO_POINTER (row);
153  GtkTreePath *path = ygtk_wrap_model_get_path (model, &iter);
154 
155  if (row == 0 && ymodel->model->rowsNb() == 1 && ymodel->model->showEmptyEntry())
156  gtk_tree_model_row_changed (model, path, &iter);
157  else
158  gtk_tree_model_row_deleted (model, path);
159  gtk_tree_path_free (path);
160 }
161 
162 static gint ygtk_wrap_model_get_n_columns (GtkTreeModel *model)
163 {
164  YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
165  return ymodel->model->columnsNb();
166 }
167 
168 static GType ygtk_wrap_model_get_column_type (GtkTreeModel *model, gint column)
169 {
170  YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
171  return ymodel->model->columnType (column);
172 }
173 
174 static void ygtk_wrap_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
175  gint column, GValue *value)
176 {
177  int row = GPOINTER_TO_INT (iter->user_data);
178  YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
179  g_value_init (value, ymodel->model->columnType (column));
180  if (row == 0 && ymodel->model->rowsNb() == 0)
181  row = -1;
182  ymodel->model->getValue (row, column, value);
183 }
184 
185 GtkTreeModel *ygtk_tree_model_new (YGtkTreeModel *model)
186 {
187  YGtkWrapModel *ymodel = (YGtkWrapModel *) g_object_new (YGTK_TYPE_WRAP_MODEL, NULL);
188  ymodel->model = model;
189  ymodel->notify = new YGtkWrapModel::Notify (ymodel);
190  model->listener = ymodel->notify;
191  return GTK_TREE_MODEL (ymodel);
192 }
193 
194 YGtkTreeModel *ygtk_tree_model_get_model (GtkTreeModel *model)
195 {
196  YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
197  return ymodel->model;
198 }
199 
200 static void ygtk_wrap_model_class_init (YGtkWrapModelClass *klass)
201 {
202  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
203  gobject_class->finalize = ygtk_wrap_model_finalize;
204 }
205 
206 static void ygtk_wrap_model_tree_model_init (GtkTreeModelIface *iface)
207 {
208  iface->get_flags = ygtk_wrap_model_get_flags;
209  iface->get_n_columns = ygtk_wrap_model_get_n_columns;
210  iface->get_column_type = ygtk_wrap_model_get_column_type;
211  iface->get_iter = ygtk_wrap_model_get_iter;
212  iface->get_path = ygtk_wrap_model_get_path;
213  iface->get_value = ygtk_wrap_model_get_value;
214  iface->iter_next = ygtk_wrap_model_iter_next;
215  iface->iter_children = ygtk_wrap_model_iter_children;
216  iface->iter_has_child = ygtk_wrap_model_iter_has_child;
217  iface->iter_n_children = ygtk_wrap_model_iter_n_children;
218  iface->iter_nth_child = ygtk_wrap_model_iter_nth_child;
219  iface->iter_parent = ygtk_wrap_model_iter_parent;
220 }
221