Remove preprocessor condition
[pspp-builds.git] / src / ui / gui / dict-display.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2007  Free Software Foundation
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17
18 #include <config.h>
19 #include <gettext.h>
20 #include <gtk/gtk.h>
21
22 #include "psppire-conf.h"
23 #include "dict-display.h"
24
25 #include "psppire-dict.h"
26 #include "helper.h"
27 #include <data/variable.h>
28 #include <data/format.h>
29
30 #define _(msgid) gettext (msgid)
31 #define N_(msgid) msgid
32
33
34 /* A GtkTreeModelFilterVisibleFunc to filter lines in the treeview */
35 static gboolean
36 filter_variables (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
37 {
38   var_predicate_func *predicate = data;
39   struct variable *var;
40   PsppireDict *dict = PSPPIRE_DICT (model);
41
42   GtkTreePath *path = gtk_tree_model_get_path (model, iter);
43
44   gint *idx = gtk_tree_path_get_indices (path);
45
46   var =  psppire_dict_get_variable (dict, *idx);
47
48   gtk_tree_path_free (path);
49
50   return predicate (var);
51 }
52
53 /* A GtkTreeCellDataFunc which sets the icon appropriate to the type
54    of variable */
55 static void
56 var_icon_cell_data_func (GtkTreeViewColumn *col,
57                        GtkCellRenderer *cell,
58                        GtkTreeModel *model,
59                        GtkTreeIter *iter,
60                        gpointer data)
61 {
62   struct variable *var;
63   gtk_tree_model_get (model, iter, DICT_TVM_COL_VAR, &var, -1);
64
65   if ( var_is_alpha (var))
66     {
67       g_object_set (cell, "stock-id", "var-string", NULL);
68     }
69   else
70     {
71       const struct fmt_spec *fs = var_get_write_format (var);
72       int cat = fmt_get_category (fs->type);
73       switch ( var_get_measure (var))
74         {
75         case MEASURE_NOMINAL:
76           g_object_set (cell, "stock-id", "var-nominal", NULL);
77           break;
78         case MEASURE_ORDINAL:
79           g_object_set (cell, "stock-id", "var-ordinal", NULL);
80           break;
81         case MEASURE_SCALE:
82           if ( ( FMT_CAT_DATE | FMT_CAT_TIME ) & cat )
83             g_object_set (cell, "stock-id", "var-date-scale", NULL);
84           else
85             g_object_set (cell, "stock-id", "var-scale", NULL);
86           break;
87         default:
88           g_assert_not_reached ();
89         };
90     }
91 }
92
93
94 void
95 get_base_model (GtkTreeModel *top_model, GtkTreeIter *top_iter,
96                 GtkTreeModel **model, GtkTreeIter *iter
97                 )
98 {
99   *model = top_model;
100   *iter = *top_iter;
101   while (GTK_IS_TREE_MODEL_FILTER (*model))
102     {
103       GtkTreeIter parent_iter = *iter;
104       GtkTreeModelFilter *parent_model = GTK_TREE_MODEL_FILTER (*model);
105
106       *model = gtk_tree_model_filter_get_model (parent_model);
107
108       gtk_tree_model_filter_convert_iter_to_child_iter (parent_model,
109                                                         iter,
110                                                         &parent_iter);
111     }
112
113   g_assert (PSPPIRE_IS_DICT (*model));
114 }
115
116 /* A GtkTreeCellDataFunc which renders the name and/or label of the
117    variable */
118 static void
119 var_description_cell_data_func (GtkTreeViewColumn *col,
120                                 GtkCellRenderer *cell,
121                                 GtkTreeModel *top_model,
122                                 GtkTreeIter *top_iter,
123                                 gpointer data)
124 {
125   struct variable *var;
126   GtkTreeIter iter;
127   GtkTreeModel *model;
128   gboolean prefer_labels = FALSE;
129
130   PsppireConf *conf = psppire_conf_new ();
131
132   psppire_conf_get_boolean (conf, "dialog-boxes", "prefer-labels",
133                             &prefer_labels);
134
135   get_base_model (top_model, top_iter, &model, &iter);
136
137   g_assert (PSPPIRE_IS_DICT (model));
138
139
140   gtk_tree_model_get (model,
141                       &iter, DICT_TVM_COL_VAR, &var, -1);
142
143   if ( var_has_label (var) && prefer_labels)
144     {
145       gchar *text = g_strdup_printf (
146                                      "<span stretch=\"condensed\">%s</span>",
147                                      var_get_label (var));
148
149       char *utf8 = pspp_locale_to_utf8 (text, -1, NULL);
150
151       g_free (text);
152       g_object_set (cell, "markup", utf8, NULL);
153       g_free (utf8);
154     }
155   else
156     {
157       char *name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL);
158       g_object_set (cell, "text", name, NULL);
159       g_free (name);
160     }
161 }
162
163
164 /* Sets the tooltip to be the name of the variable under the cursor */
165 static gboolean
166 set_tooltip_for_variable (GtkTreeView  *treeview,
167                           gint        x,
168                           gint        y,
169                           gboolean    keyboard_mode,
170                           GtkTooltip *tooltip,
171                           gpointer    user_data)
172
173 {
174   gint bx, by;
175   GtkTreeIter iter;
176   GtkTreePath *path;
177   GtkTreeModel *tree_model;
178   struct variable *var = NULL;
179   gboolean ok;
180
181
182   gtk_tree_view_convert_widget_to_bin_window_coords (treeview,
183                                                      x, y, &bx, &by);
184
185   if (!gtk_tree_view_get_path_at_pos (treeview, bx, by,
186                                       &path, NULL, NULL, NULL))
187     return FALSE;
188
189   tree_model = gtk_tree_view_get_model (treeview);
190
191
192   gtk_tree_view_set_tooltip_row (treeview, tooltip, path);
193
194   ok = gtk_tree_model_get_iter (tree_model, &iter, path);
195
196   gtk_tree_path_free (path);
197   if (!ok)
198     return FALSE;
199
200
201   gtk_tree_model_get (tree_model, &iter, DICT_TVM_COL_VAR,  &var, -1);
202
203   if ( ! var_has_label (var))
204     return FALSE;
205
206   {
207     gchar *tip ;
208     gboolean prefer_labels = FALSE;
209
210     PsppireConf *conf = psppire_conf_new ();
211
212     psppire_conf_get_boolean (conf, "dialog-boxes", "prefer-labels",
213                               &prefer_labels);
214
215     if ( prefer_labels )
216       tip = pspp_locale_to_utf8 (var_get_name (var), -1, NULL);
217     else
218       tip = pspp_locale_to_utf8 (var_get_label (var), -1, NULL);
219
220     gtk_tooltip_set_text (tooltip, tip);
221
222     g_free (tip);
223   }
224
225   return TRUE;
226 }
227
228    /* Sets up TREEVIEW to display the variables of DICT.
229    MODE is the selection mode for TREEVIEW.
230    PREDICATE determines which variables should be visible, or NULL if
231    all are to be visible.
232  */
233 void
234 attach_dictionary_to_treeview (GtkTreeView *treeview, PsppireDict *dict,
235                                GtkSelectionMode mode,
236                                var_predicate_func *predicate
237                                )
238 {
239   GtkTreeViewColumn *col;
240
241   GtkTreeSelection *selection =
242     gtk_tree_view_get_selection (treeview);
243
244   GtkCellRenderer *renderer;
245
246   GtkTreeModel *model ;
247
248   if ( predicate )
249     {
250       model = gtk_tree_model_filter_new (GTK_TREE_MODEL (dict),
251                                           NULL);
252
253       gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model),
254                                               filter_variables,
255                                               predicate,
256                                               NULL);
257     }
258   else
259     {
260       model = GTK_TREE_MODEL (dict);
261     }
262
263   gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), model);
264
265
266   col = gtk_tree_view_column_new ();
267   gtk_tree_view_column_set_title (col, _("Variable"));
268
269   renderer = gtk_cell_renderer_pixbuf_new ();
270   gtk_tree_view_column_pack_start (col, renderer, FALSE);
271
272   gtk_tree_view_column_set_cell_data_func (col, renderer,
273                                            var_icon_cell_data_func,
274                                            NULL, NULL);
275
276
277   renderer = gtk_cell_renderer_text_new ();
278   gtk_tree_view_column_pack_start (col, renderer, TRUE);
279   gtk_tree_view_column_set_cell_data_func (col, renderer,
280                                            var_description_cell_data_func,
281                                            NULL, NULL);
282
283   g_object_set (renderer, "ellipsize-set", TRUE, NULL);
284   g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL);
285
286   gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
287
288   /* FIXME: make this a value in terms of character widths */
289   gtk_tree_view_column_set_min_width (col, 150);
290
291   gtk_tree_view_append_column (treeview, col);
292
293   gtk_tree_selection_set_mode (selection, mode);
294
295   g_object_set (treeview, "has-tooltip", TRUE, NULL);
296
297   g_signal_connect (treeview, "query-tooltip", G_CALLBACK (set_tooltip_for_variable), NULL);
298 }
299
300
301 void
302 insert_source_row_into_entry (GtkTreeIter iter,
303                               GtkWidget *dest,
304                               GtkTreeModel *model,
305                               gpointer data
306                               )
307 {
308   GtkTreePath *path;
309   GtkTreeModel *dict;
310   gint *idx;
311   struct variable *var;
312   GtkTreeIter dict_iter;
313   gchar *name;
314
315   g_return_if_fail (GTK_IS_ENTRY(dest));
316
317   get_base_model (model, &iter, &dict, &dict_iter);
318
319   path = gtk_tree_model_get_path (GTK_TREE_MODEL (dict), &dict_iter);
320
321   idx = gtk_tree_path_get_indices (path);
322
323   var =  psppire_dict_get_variable (PSPPIRE_DICT (dict), *idx);
324
325   gtk_tree_path_free (path);
326
327   name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL);
328   gtk_entry_set_text (GTK_ENTRY (dest),  name);
329   g_free (name);
330 }
331
332
333
334 void
335 insert_source_row_into_tree_view (GtkTreeIter iter,
336                                   GtkWidget *dest,
337                                   GtkTreeModel *model,
338                                   gpointer data
339                                   )
340 {
341   GtkTreePath *path;
342   GtkTreeIter dest_iter;
343   GtkTreeIter dict_iter;
344   gint *row ;
345   GtkTreeModel *destmodel = gtk_tree_view_get_model ( GTK_TREE_VIEW (dest));
346
347   GtkTreeModel *dict;
348
349
350   get_base_model (model, &iter, &dict, &dict_iter);
351
352   path = gtk_tree_model_get_path (dict, &dict_iter);
353
354   row = gtk_tree_path_get_indices (path);
355
356   gtk_list_store_append (GTK_LIST_STORE (destmodel),  &dest_iter);
357   gtk_list_store_set (GTK_LIST_STORE (destmodel), &dest_iter, 0, *row, -1);
358
359   gtk_tree_path_free (path);
360 }
361
362
363 gboolean
364 is_currently_in_entry (GtkTreeModel *model, GtkTreeIter *iter,
365                        PsppireSelector *selector)
366 {
367   gboolean result;
368   gchar *name;
369   GtkTreeIter dict_iter;
370   GtkTreeModel *dict;
371   struct variable *var;
372   gint dict_index;
373   gint *indeces;
374   GtkTreePath *path;
375   const gchar *text =   gtk_entry_get_text (GTK_ENTRY (selector->dest));
376
377   get_base_model (model, iter, &dict, &dict_iter);
378
379   path = gtk_tree_model_get_path (dict, &dict_iter);
380
381   indeces = gtk_tree_path_get_indices (path);
382
383   dict_index = indeces [0];
384
385   var = psppire_dict_get_variable (PSPPIRE_DICT (dict), dict_index);
386
387   gtk_tree_path_free (path);
388
389   name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL);
390   result = ( 0 == strcmp (text, name));
391   g_free (name);
392
393   return result;
394 }
395
396