GnuCash  5.6-150-g038405b370+
gnc-gui-query.c
1 /********************************************************************\
2  * gnc-gui-query.c -- functions for creating dialogs for GnuCash *
3  * Copyright (C) 1998, 1999, 2000 Linas Vepstas *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21 \********************************************************************/
22 
23 #include <config.h>
24 
25 #include <glib/gi18n.h>
26 
27 #include "dialog-utils.h"
28 #include "qof.h"
29 #include "gnc-gui-query.h"
30 #include "gnc-ui.h"
31 
32 #define INDEX_LABEL "index"
33 
34 /* This static indicates the debugging module that this .o belongs to. */
35 /* static short module = MOD_GUI; */
36 
37 /********************************************************************\
38  * gnc_ok_cancel_dialog *
39  * display a message, and asks the user to press "Ok" or "Cancel" *
40  * *
41  * NOTE: This function does not return until the dialog is closed *
42  * *
43  * Args: parent - the parent window *
44  * default - the button that will be the default *
45  * message - the message to display *
46  * format - the format string for the message to display *
47  * This is a standard 'printf' style string. *
48  * args - a pointer to the first argument for the format *
49  * string. *
50  * Return: the result the user selected *
51 \********************************************************************/
52 gint
53 gnc_ok_cancel_dialog(GtkWindow *parent,
54  gint default_result,
55  const gchar *format, ...)
56 {
57  GtkWidget *dialog = NULL;
58  gint result;
59  gchar *buffer;
60  va_list args;
61 
62  if (!parent)
63  parent = gnc_ui_get_main_window (NULL);
64 
65  va_start(args, format);
66  buffer = g_strdup_vprintf(format, args);
67  dialog = gtk_message_dialog_new (parent,
68  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
69  GTK_MESSAGE_QUESTION,
70  GTK_BUTTONS_OK_CANCEL,
71  "%s",
72  buffer);
73  g_free(buffer);
74  va_end(args);
75 
76  if (!parent)
77  gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
78 
79  gtk_dialog_set_default_response (GTK_DIALOG(dialog), default_result);
80  result = gtk_dialog_run(GTK_DIALOG(dialog));
81  gtk_widget_destroy (dialog);
82  return(result);
83 }
84 
85 
86 
87 /********************************************************************\
88  * gnc_verify_dialog *
89  * display a message, and asks the user to press "Yes" or "No" *
90  * *
91  * NOTE: This function does not return until the dialog is closed *
92  * *
93  * Args: parent - the parent window *
94  * yes_is_default - If true, "Yes" is default, *
95  * "No" is the default button. *
96  * format - the format string for the message to display *
97  * This is a standard 'printf' style string. *
98  * args - a pointer to the first argument for the format *
99  * string. *
100 \********************************************************************/
101 gboolean
102 gnc_verify_dialog(GtkWindow *parent, gboolean yes_is_default,
103  const gchar *format, ...)
104 {
105  GtkWidget *dialog;
106  gchar *buffer;
107  gint result;
108  va_list args;
109 
110  if (!parent)
111  parent = gnc_ui_get_main_window (NULL);
112 
113  va_start(args, format);
114  buffer = g_strdup_vprintf(format, args);
115  dialog = gtk_message_dialog_new (parent,
116  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
117  GTK_MESSAGE_QUESTION,
118  GTK_BUTTONS_YES_NO,
119  "%s",
120  buffer);
121  g_free(buffer);
122  va_end(args);
123 
124  if (!parent)
125  gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
126 
127  gtk_dialog_set_default_response(GTK_DIALOG(dialog),
128  (yes_is_default ? GTK_RESPONSE_YES : GTK_RESPONSE_NO));
129  result = gtk_dialog_run(GTK_DIALOG(dialog));
130  gtk_widget_destroy (dialog);
131  return (result == GTK_RESPONSE_YES);
132 }
133 
134 static void
135 gnc_message_dialog_common (GtkWindow *parent, const gchar *format, GtkMessageType msg_type, va_list args)
136 {
137  GtkWidget *dialog = NULL;
138  gchar *buffer;
139 
140  if (!parent)
141  parent = gnc_ui_get_main_window (NULL);
142 
143  buffer = g_strdup_vprintf(format, args);
144  dialog = gtk_message_dialog_new (parent,
145  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
146  msg_type,
147  GTK_BUTTONS_CLOSE,
148  "%s",
149  buffer);
150  g_free(buffer);
151 
152  if (!parent)
153  gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
154 
155  gtk_dialog_run (GTK_DIALOG (dialog));
156  gtk_widget_destroy (dialog);
157 }
158 
159 /********************************************************************\
160  * gnc_info_dialog *
161  * displays an information dialog box *
162  * *
163  * Args: parent - the parent window *
164  * format - the format string for the message to display *
165  * This is a standard 'printf' style string. *
166  * args - a pointer to the first argument for the format *
167  * string. *
168  * Return: none *
169 \********************************************************************/
170 void
171 gnc_info_dialog (GtkWindow *parent, const gchar *format, ...)
172 {
173  va_list args;
174 
175  va_start(args, format);
176  gnc_message_dialog_common (parent, format, GTK_MESSAGE_INFO, args);
177  va_end(args);
178 }
179 
180 
181 
182 /********************************************************************\
183  * gnc_warning_dialog *
184  * displays a warning dialog box *
185  * *
186  * Args: parent - the parent window *
187  * format - the format string for the message to display *
188  * This is a standard 'printf' style string. *
189  * args - a pointer to the first argument for the format *
190  * string. *
191  * Return: none *
192 \********************************************************************/
193 
194 void
195 gnc_warning_dialog (GtkWindow *parent, const gchar *format, ...)
196 {
197  va_list args;
198 
199  va_start(args, format);
200  gnc_message_dialog_common (parent, format, GTK_MESSAGE_WARNING, args);
201  va_end(args);
202 }
203 
204 
205 /********************************************************************\
206  * gnc_error_dialog *
207  * displays an error dialog box *
208  * *
209  * Args: parent - the parent window *
210  * format - the format string for the message to display *
211  * This is a standard 'printf' style string. *
212  * args - a pointer to the first argument for the format *
213  * string. *
214  * Return: none *
215 \********************************************************************/
216 void gnc_error_dialog (GtkWindow* parent, const char* format, ...)
217 {
218  va_list args;
219 
220  va_start(args, format);
221  gnc_message_dialog_common (parent, format, GTK_MESSAGE_ERROR, args);
222  va_end(args);
223 }
224 
225 static void
226 gnc_choose_radio_button_cb(GtkWidget *w, gpointer data)
227 {
228  int *result = data;
229 
230  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
231  *result = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), INDEX_LABEL));
232 }
233 
234 /********************************************************************
235  gnc_choose_radio_option_dialog
236 
237  display a group of radio_buttons and return the index of
238  the selected one
239 */
240 
241 int
242 gnc_choose_radio_option_dialog(GtkWidget *parent,
243  const char *title,
244  const char *msg,
245  const char *button_name,
246  int default_value,
247  GList *radio_list)
248 {
249  int radio_result = 0; /* initial selected value is first one */
250  GtkWidget *vbox;
251  GtkWidget *main_vbox;
252  GtkWidget *label;
253  GtkWidget *radio_button;
254  GtkWidget *dialog;
255  GtkWidget *dvbox;
256  GSList *group = NULL;
257  GList *node;
258  int i;
259 
260  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
261  gtk_box_set_homogeneous (GTK_BOX (main_vbox), FALSE);
262  gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 6);
263  gtk_widget_show(main_vbox);
264 
265  label = gtk_label_new(msg);
266  gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
267  gtk_box_pack_start(GTK_BOX(main_vbox), label, FALSE, FALSE, 0);
268  gtk_widget_show(label);
269 
270  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
271  gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE);
272  gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
273  gtk_container_add(GTK_CONTAINER(main_vbox), vbox);
274  gtk_widget_show(vbox);
275 
276  for (node = radio_list, i = 0; node; node = node->next, i++)
277  {
278  radio_button = gtk_radio_button_new_with_mnemonic(group, node->data);
279  group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio_button));
280  gtk_widget_set_halign (GTK_WIDGET(radio_button), GTK_ALIGN_START);
281 
282  if (i == default_value) /* default is first radio button */
283  {
284  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button), TRUE);
285  radio_result = default_value;
286  }
287 
288  gtk_widget_show(radio_button);
289  gtk_box_pack_start(GTK_BOX(vbox), radio_button, FALSE, FALSE, 0);
290  g_object_set_data(G_OBJECT(radio_button), INDEX_LABEL, GINT_TO_POINTER(i));
291  g_signal_connect(radio_button, "clicked",
292  G_CALLBACK(gnc_choose_radio_button_cb),
293  &radio_result);
294  }
295 
296  if (!button_name)
297  button_name = _("_OK");
298  dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW(parent),
299  GTK_DIALOG_DESTROY_WITH_PARENT,
300  _("_Cancel"), GTK_RESPONSE_CANCEL,
301  button_name, GTK_RESPONSE_OK,
302  NULL);
303 
304  /* default to ok */
305  gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
306 
307  dvbox = gtk_dialog_get_content_area (GTK_DIALOG(dialog));
308 
309  gtk_box_pack_start(GTK_BOX(dvbox), main_vbox, TRUE, TRUE, 0);
310 
311  if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
312  radio_result = -1;
313 
314  gtk_widget_destroy (dialog);
315 
316  return radio_result;
317 }
318 
319 static gchar *
320 gnc_input_dialog_internal (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input, gboolean use_entry)
321 {
322  gint result;
323  GtkWidget *view;
324  GtkTextBuffer *buffer;
325  gchar *user_input = NULL;
326  GtkTextIter start, end;
327 
328  /* Create the widgets */
329  GtkWidget* dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
330  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
331  _("_OK"), GTK_RESPONSE_ACCEPT,
332  _("_Cancel"), GTK_RESPONSE_REJECT,
333  NULL);
334  GtkWidget* content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
335 
336  // add a label
337  GtkWidget* label = gtk_label_new (msg);
338  gtk_box_pack_start(GTK_BOX(content_area), label, FALSE, FALSE, 0);
339 
340  // add a textview or an entry.
341  if (use_entry)
342  {
343  view = gtk_entry_new ();
344  gtk_entry_set_text (GTK_ENTRY (view), default_input);
345  }
346  else
347  {
348  view = gtk_text_view_new ();
349  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD_CHAR);
350  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
351  gtk_text_buffer_set_text (buffer, default_input, -1);
352  }
353  gtk_box_pack_start(GTK_BOX(content_area), view, TRUE, TRUE, 0);
354 
355  // run the dialog
356  gtk_widget_show_all (dialog);
357  result = gtk_dialog_run (GTK_DIALOG (dialog));
358 
359  if (result != GTK_RESPONSE_REJECT)
360  {
361  if (use_entry)
362  user_input = g_strdup (gtk_entry_get_text ((GTK_ENTRY (view))));
363  else
364  {
365  gtk_text_buffer_get_start_iter (buffer, &start);
366  gtk_text_buffer_get_end_iter (buffer, &end);
367  user_input = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
368  }
369  }
370 
371  gtk_widget_destroy (dialog);
372 
373  return user_input;
374 }
375 
376 /********************************************************************\
377  * gnc_input_dialog *
378  * simple convenience dialog to get a single value from the user *
379  * user may choose between "Ok" and "Cancel" *
380  * *
381  * NOTE: This function does not return until the dialog is closed *
382  * *
383  * Args: parent - the parent window or NULL *
384  * title - the title of the dialog *
385  * msg - the message to display *
386  * default_input - will be displayed as default input *
387  * Return: the input (text) the user entered, if pressed "Ok" *
388  * NULL, if pressed "Cancel" *
389  \********************************************************************/
390 gchar *
391 gnc_input_dialog (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input)
392 {
393  return gnc_input_dialog_internal (parent, title, msg, default_input, FALSE);
394 }
395 
396 /********************************************************************\
397  * gnc_input_dialog_with_entry *
398  * Similar to gnc_input_dialog but use a single line entry widget *
399  * user may choose between "Ok" and "Cancel" *
400  \********************************************************************/
401 gchar *
402 gnc_input_dialog_with_entry (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input)
403 {
404  return gnc_input_dialog_internal (parent, title, msg, default_input, TRUE);
405 }
406 
407 void
408 gnc_info2_dialog (GtkWidget *parent, const gchar *title, const gchar *msg)
409 {
410  GtkWidget *view;
411  GtkTextBuffer *buffer;
412  gint width, height;
413 
414  /* Create the widgets */
415  GtkWidget* dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
416  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
417  _("_OK"), GTK_RESPONSE_ACCEPT,
418  NULL);
419  GtkWidget* content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
420 
421  // add a scroll area
422  GtkWidget* scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
423  gtk_box_pack_start(GTK_BOX(content_area), scrolledwindow, TRUE, TRUE, 0);
424 
425  // add a textview
426  view = gtk_text_view_new ();
427  gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
428  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
429  gtk_text_buffer_set_text (buffer, msg, -1);
430  gtk_container_add (GTK_CONTAINER (scrolledwindow), view);
431 
432  // run the dialog
433  if (parent)
434  {
435  gtk_window_get_size (GTK_WINDOW(parent), &width, &height);
436  gtk_window_set_default_size (GTK_WINDOW(dialog), width, height);
437  }
438  gtk_widget_show_all (dialog);
439  gtk_dialog_run (GTK_DIALOG (dialog));
440  gtk_widget_destroy (dialog);
441 }
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.