PIPS
gtk_mchoose.c
Go to the documentation of this file.
1 /*
2 
3  $Id: gtk_mchoose.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 /* Multiple choices handling */
29 
30 #include <stdio.h>
31 
32 #include <sys/time.h>
33 #include <sys/resource.h>
34 
35 #include "genC.h"
36 #include "misc.h"
37 
38 #undef test_undefined // also defined in glib included from gtk
39 #include <gtk/gtk.h>
40 
41 #include "gpips.h"
42 
45 static GtkListStore *choices;
46 
47 enum {
49 };
50 
51 static void (*apply_on_mchoices)( gen_array_t) = NULL;
52 static void (*cancel_on_mchoices)(void) = NULL;
53 
54 #if 0
55 static void mchoose_help_notify(GtkWidget * widget __attribute__((unused)), gpointer data __attribute__((unused))) {
56  display_help("MultipleChoice");
57 }
58 #endif
59 
60 static void mchoose_ok_notify(GtkWidget * widget __attribute__((unused)), gpointer data __attribute__((unused))) {
61  gen_array_t mchoices_args = gen_array_make(0);
62 
63  GtkTreeSelection * selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(
64  choices_list));
65 
66  gchar *buffer, *mchoices_notify_buffer;
67  int mchoices_length = 0;
68 // int nchoices;
69  int len;
70 // int item_is_in_the_list = FALSE;
71  char * p;
72 
73 // nchoices = (int) xv_get(choices, PANEL_LIST_NROWS, NULL);
74 
75  mchoices_notify_buffer = strdup(gtk_label_get_text(GTK_LABEL(mchoices_label)));
76  /* Upperbound size for the scanf buffer: */
77  buffer = (char *) malloc(strlen(mchoices_notify_buffer) + 1);
78 
79  p = mchoices_notify_buffer;
80  while (sscanf(p, "%s%n", buffer, &len) == 1) {
81  gen_array_dupaddto(mchoices_args, mchoices_length++, buffer);
82 // item_is_in_the_list = FALSE;
83 // for (int i = 0; i < nchoices; i++)
84 // if (strcmp((char *) xv_get(choices, PANEL_LIST_STRING, i), buffer)
85 // == 0) {
86 // item_is_in_the_list = TRUE;
87 // break;
88 // }
89 // if (item_is_in_the_list == FALSE)
90 // break;
91  p += len;
92  }
93 
94  g_free(mchoices_notify_buffer);
95  g_free(buffer);
96  //
97  // /* At least on item selected, and in the list.
98  // RK, 21/05/1993.
99  // */
100  // if (mchoices_length == 0 || item_is_in_the_list == FALSE) {
101  // char *s;
102  // s = mchoices_length == 0 ? "You have to select at least 1 item!"
103  // : "You have selected an item not in the choice list!";
104  // gen_array_full_free(mchoices_args);
105  // prompt_user(s);
106  // return;
107  // }
108  if (gtk_tree_selection_count_selected_rows(selection) == 0) {
109  prompt_user("You have to select at least 1 item !");
110  return;
111  }
112 
113  hide_window(mchoose_window, NULL, NULL);
114 
115  // ?
116  // xv_set(mchoices, PANEL_NOTIFY_PROC, NULL);
117 
118  (*apply_on_mchoices)(mchoices_args);
119  gen_array_full_free(mchoices_args);
120 
121  /* Delay the graphics transformations. RK, 21/05/1993. */
122 
123  gtk_list_store_clear(choices);
124 
125  gtk_label_set_text(GTK_LABEL(mchoices_label), "");
126 }
127 
128 static void mchoose_cancel_notify(GtkWidget * widget __attribute__((unused)), gpointer data __attribute__((unused))) {
129  hide_window(mchoose_window, NULL, NULL);
130 
131  // The OK button becomes inactive through RETURN:
132  gtk_window_set_default(GTK_WINDOW(mchoose_window), NULL);
133 
134  // ?
135  //xv_set(mchoices, PANEL_NOTIFY_PROC, NULL);
136 
137  (*cancel_on_mchoices)();
138 
139  gtk_list_store_clear(choices);
140 
141  gtk_label_set_text(GTK_LABEL(mchoices_label), "");
142 }
143 
144 /* Avoid the mchoose_frame destruction and act as cancel: */
145 static void mchoose_window_done_proc(GtkWidget * window __attribute__((unused)), gpointer data __attribute__((unused))) {
146  mchoose_cancel_notify(NULL, NULL);
147 }
148 
149 static void concat_labels(gpointer _row, gpointer _label) {
150  GtkTreePath * path = (GtkTreePath *) _row;
151  gchar ** label = (gchar **) _label;
152  gchar * new_label;
153 
154  GValue path_associated_value = { 0, };
155  GtkTreeIter iter;
156  gtk_tree_model_get_iter(GTK_TREE_MODEL(choices), &iter, path);
157  gtk_tree_model_get_value(GTK_TREE_MODEL(choices), &iter,
158  M_AVAILABLE_CHOICES_COLUMN_ID, &path_associated_value);
159  gchar * path_associated_value_string = (gchar *) g_value_get_string(
160  &path_associated_value);
161 
162  new_label = strdup(concatenate(*label, path_associated_value_string, " ",
163  NULL));
164  g_free(*label);
165  *label = new_label;
166 }
167 
168 /* Function used to update the text panel according to the list panel: */
169 //int static mchoose_notify(Panel_item item, char * item_string,
170 // Xv_opaque client_data, Panel_list_op op, Event * event, int row) {
171 static void mchoose_callback(GtkTreeSelection * selection, gpointer data __attribute__((unused))) {
172  GList * selected_rows;
173  gchar * new_mchoices_label;
174 
175  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(choices_list));
176  new_mchoices_label = strdup("");
177 
178  /* Make the PANEL_VALUE of mchoices a string that is all the
179  names of the selected files: */
180  selected_rows = gtk_tree_selection_get_selected_rows(GTK_TREE_SELECTION(
181  selection), (GtkTreeModel**)&choices);
182 
183  g_list_foreach(selected_rows, concat_labels, &new_mchoices_label);
184  g_list_free(selected_rows);
185 
186  gtk_label_set_text(GTK_LABEL(mchoices_label), new_mchoices_label);
187  g_free(new_mchoices_label);
188 }
189 
190 /* When we press on the "(De)Select" all button, select or deselect
191  all the items. */
192 static void mchoose_de_select_all_notify(GtkWidget * widget __attribute__((unused)), gpointer data __attribute__((unused))) {
193  GtkTreeSelection * selection;
194 
195  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(choices_list));
196 
197  static bool select_all_when_press_this_button = TRUE;
198 
199  if (select_all_when_press_this_button) {
200  gtk_tree_selection_select_all(GTK_TREE_SELECTION(selection));
201  } else {
202  gtk_tree_selection_unselect_all(GTK_TREE_SELECTION(selection));
203  }
204 
205  /* Update the "Current choices": */
206  mchoose_callback(selection, NULL);
207 
208  /* Next time we press this button, do the opposite: */
209  select_all_when_press_this_button = !select_all_when_press_this_button;
210 }
211 
212 void mchoose(char * title, gen_array_t array, void(*function_ok)( gen_array_t),
213  void(*function_cancel)(void)) {
214  int i, argc = gen_array_nitems(array);
215 
216  GtkTreeIter iter;
218 
219  apply_on_mchoices = function_ok;
220  cancel_on_mchoices = function_cancel;
221 
222  gtk_window_set_title(GTK_WINDOW(mchoose_window), title);
223  gtk_list_store_clear(choices);
224 
225  for (i = 0; i < argc; i++) {
226  string name = gen_array_item(array, i);
227  gtk_list_store_append(GTK_LIST_STORE(choices), &iter);
228  gtk_list_store_set(choices, &iter, M_AVAILABLE_CHOICES_COLUMN_ID, name,
229  -1);
230  }
231  gtk_widget_show(mchoose_window);
232 
233  /* move the pointer to the center of the query window */
234  // Sans vouloir remettre en question le design de la chose
235  // A priori je ne traduirai pas ça à moins qu'on ne le
236  // demande expressément...
237  //pointer_in_center_of_frame(mchoose_frame);
238  //?
239  // xv_set(mchoices, PANEL_NOTIFY_PROC, mchoose_ok_notify, NULL);
240 }
241 
243  guint i;
244  GtkWidget *vbox, *buttons_hbox;
245  GtkTreeIter iter;
246  GtkTreeSelection * _select;
247  GtkWidget *deselect_button;
248 
249  GtkWidget * scrolled_window;
250  scrolled_window = gtk_scrolled_window_new(NULL, NULL);
251  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
252  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
253 
254  vbox = gtk_vbox_new(FALSE, 0);
255  buttons_hbox = gtk_hbox_new(FALSE, 0);
256  gtk_container_add(GTK_CONTAINER(mchoose_window), vbox);
257 
258  // mchoose_panel = xv_create(mchoose_frame, PANEL, NULL);
259 
260 
261  // mchoices = xv_create(mchoose_panel, PANEL_TEXT, PANEL_LABEL_STRING,
262  // "Current choices", PANEL_VALUE_DISPLAY_LENGTH, 30,
263  // PANEL_VALUE_STORED_LENGTH, 12800,
264  // /* PANEL_NOTIFY_PROC, mchoose_ok_notify, */
265  // XV_X, xv_col(mchoose_panel, 0), NULL);
266  gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new("Current choices : "),
267  FALSE, FALSE, 0);
268  mchoices_label = gtk_label_new("");
269  gtk_box_pack_start(GTK_BOX(vbox), mchoices_label, FALSE, FALSE, 0);
270  gtk_widget_show(mchoices_label);
271 
272  mchoose_frame = gtk_frame_new("test");
273 
274  // choices = xv_create(mchoose_panel, PANEL_LIST, PANEL_LABEL_STRING,
275  // "Available choices", PANEL_LIST_DISPLAY_ROWS, 5, PANEL_NOTIFY_PROC,
276  // mchoose_notify, PANEL_CHOOSE_ONE, FALSE, XV_X, xv_col(
277  // mchoose_panel, 0), XV_Y, xv_rows(mchoose_panel, 1), NULL);
278  choices = gtk_list_store_new(M_COLUMNS_NUMBER, G_TYPE_STRING);
279  for (i = 0; i < 5; i++) {
280  gtk_list_store_append(GTK_LIST_STORE(choices), &iter);
281  gtk_list_store_set(choices, &iter, M_AVAILABLE_CHOICES_COLUMN_ID, "",
282  -1);
283  }
284 
285  choices_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(choices));
286  GtkCellRenderer * renderer = gtk_cell_renderer_text_new();
287  GtkTreeViewColumn * column;
288  column = gtk_tree_view_column_new_with_attributes("Available choices",
289  renderer, "text", M_AVAILABLE_CHOICES_COLUMN_ID, NULL);
290  gtk_tree_view_append_column(GTK_TREE_VIEW(choices_list), column);
291 
292  _select = gtk_tree_view_get_selection(GTK_TREE_VIEW(choices_list));
293  gtk_tree_selection_set_mode(GTK_TREE_SELECTION(_select),
294  GTK_SELECTION_MULTIPLE);
295  g_signal_connect(_select, "changed", G_CALLBACK(mchoose_callback), NULL);
296 
297  gtk_container_add(GTK_CONTAINER(scrolled_window), choices_list);
298  gtk_container_add(GTK_CONTAINER(mchoose_frame), scrolled_window);
299  gtk_box_pack_start(GTK_BOX(vbox), mchoose_frame, TRUE, TRUE, 5);
300  // gtk_box_pack_start(GTK_BOX(window_vbox), choices_list, FALSE, FALSE, 0);
301  gtk_widget_show(choices_list);
302 
303  // ok = xv_create(mchoose_panel, PANEL_BUTTON, PANEL_LABEL_STRING, "OK",
304  // PANEL_NOTIFY_PROC, mchoose_ok_notify, XV_X,
305  // xv_col(mchoose_panel, 5), XV_Y, xv_rows(mchoose_panel, 5), NULL);
306  ok_button = gtk_button_new_with_label("OK");
307  gtk_signal_connect(GTK_OBJECT(ok_button), "clicked", GTK_SIGNAL_FUNC(
308  mchoose_ok_notify), NULL);
309  gtk_box_pack_start(GTK_BOX(buttons_hbox), ok_button, FALSE, FALSE, 5);
310 
311  // (void) xv_create(mchoose_panel, PANEL_BUTTON, PANEL_LABEL_STRING,
312  // "(De)Select all", PANEL_NOTIFY_PROC, mchoose_de_select_all_notify,
313  // NULL);
314  deselect_button = gtk_button_new_with_label("(De)Select all");
315  gtk_signal_connect(GTK_OBJECT(deselect_button), "clicked", GTK_SIGNAL_FUNC(
317  gtk_box_pack_start(GTK_BOX(buttons_hbox), deselect_button, FALSE, FALSE, 5);
318 
319  // cancel = xv_create(mchoose_panel, PANEL_BUTTON, PANEL_LABEL_STRING,
320  // "Cancel", PANEL_NOTIFY_PROC, mchoose_cancel_notify, NULL);
321  cancel_button = gtk_button_new_with_label("Cancel");
322  gtk_signal_connect(GTK_OBJECT(cancel_button), "clicked", GTK_SIGNAL_FUNC(
323  mchoose_cancel_notify), NULL);
324  gtk_box_pack_start(GTK_BOX(buttons_hbox), cancel_button, FALSE, FALSE, 5);
325 
326  // help = xv_create(mchoose_panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Help",
327  // PANEL_NOTIFY_PROC, mchoose_help_notify, NULL);
328  help_button = gtk_button_new_with_label("Help");
329  gtk_signal_connect(GTK_OBJECT(help_button), "clicked", GTK_SIGNAL_FUNC(
330  mchoose_ok_notify), NULL);
331  gtk_box_pack_start(GTK_BOX(buttons_hbox), help_button, FALSE, FALSE, 5);
332 
333  gtk_box_pack_start(GTK_BOX(vbox), buttons_hbox, FALSE, FALSE, 5);
334  // xv_set(mchoose_frame, FRAME_DONE_PROC, mchoose_frame_done_proc, NULL);
335  gtk_window_set_default(GTK_WINDOW(mchoose_window), ok_button);
336 
337  gtk_signal_connect(GTK_OBJECT(mchoose_window), "delete-event",
338  GTK_SIGNAL_FUNC(mchoose_window_done_proc), NULL);
339 
340  gtk_widget_show_all(vbox);
341 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
size_t gen_array_nitems(const gen_array_t a)
Definition: array.c:131
void gen_array_full_free(gen_array_t a)
Definition: array.c:77
gen_array_t gen_array_make(size_t size)
declarations...
Definition: array.c:40
void gen_array_dupaddto(gen_array_t a, size_t i, void *what)
Definition: array.c:111
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143
void * malloc(YYSIZE_T)
GtkWidget * mchoose_frame
Definition: gpips-local.h:42
GtkWidget * mchoose_window
Definition: gpips-local.h:36
void display_help(char *topic)
Definition: gtk_help.c:50
void prompt_user(string a_printf_format,...)
Definition: gtk_log.c:66
static GtkWidget * ok_button
Definition: gtk_mchoose.c:43
static GtkListStore * choices
Definition: gtk_mchoose.c:45
static void(* apply_on_mchoices)(gen_array_t)
Definition: gtk_mchoose.c:51
static GtkWidget * help_button
Definition: gtk_mchoose.c:44
static void mchoose_callback(GtkTreeSelection *selection, gpointer data __attribute__((unused)))
Function used to update the text panel according to the list panel:
Definition: gtk_mchoose.c:171
static GtkWidget * cancel_button
Definition: gtk_mchoose.c:43
static void(* cancel_on_mchoices)(void)
Definition: gtk_mchoose.c:52
void create_mchoose_window()
Definition: gtk_mchoose.c:242
@ M_AVAILABLE_CHOICES_COLUMN_ID
Definition: gtk_mchoose.c:48
@ M_COLUMNS_NUMBER
Definition: gtk_mchoose.c:48
void mchoose(char *title, gen_array_t array, void(*function_ok)(gen_array_t), void(*function_cancel)(void))
Definition: gtk_mchoose.c:212
static void mchoose_ok_notify(GtkWidget *widget __attribute__((unused)), gpointer data __attribute__((unused)))
Definition: gtk_mchoose.c:60
static GtkWidget * mchoices_label
Multiple choices handling.
Definition: gtk_mchoose.c:43
static GtkWidget * choices_list
Definition: gtk_mchoose.c:43
static void concat_labels(gpointer _row, gpointer _label)
Definition: gtk_mchoose.c:149
static void mchoose_de_select_all_notify(GtkWidget *widget __attribute__((unused)), gpointer data __attribute__((unused)))
When we press on the "(De)Select" all button, select or deselect all the items.
Definition: gtk_mchoose.c:192
static void mchoose_cancel_notify(GtkWidget *widget __attribute__((unused)), gpointer data __attribute__((unused)))
Definition: gtk_mchoose.c:128
static void mchoose_window_done_proc(GtkWidget *window __attribute__((unused)), gpointer data __attribute__((unused)))
Avoid the mchoose_frame destruction and act as cancel:
Definition: gtk_mchoose.c:145
gint hide_window(GtkWidget *window, GdkEvent *ev __attribute__((unused)), gpointer data __attribute__((unused)))
Definition: gtk_utils.c:89
struct _gen_array_chunk_t * gen_array_t
Definition: newgen_array.h:24
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
char * strdup()
static entity array
static string buffer
Definition: string.c:113
static void mchoose_help_notify(Panel_item item, Event *event)
Definition: xv_mchoose.c:49