GnuCash  5.6-150-g038405b370+
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 gboolean
86 gnc_action_dialog (GtkWindow *parent, const gchar *action,
87  gboolean action_default, const gchar *format, ...)
88 {
89  g_return_val_if_fail (action, FALSE);
90 
91  if (!parent)
92  parent = gnc_ui_get_main_window (NULL);
93 
94  va_list args;
95  va_start(args, format);
96  gchar *buffer = g_strdup_vprintf(format, args);
97  va_end(args);
98 
99  GtkWidget *dialog = gtk_message_dialog_new (parent,
100  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
101  GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
102  "%s", buffer);
103 
104  gtk_dialog_add_button (GTK_DIALOG(dialog), action, GTK_RESPONSE_ACCEPT);
105  gtk_dialog_add_button (GTK_DIALOG(dialog), _("_Cancel"), GTK_RESPONSE_CANCEL);
106  gtk_dialog_set_default_response (GTK_DIALOG(dialog), action_default ?
107  GTK_RESPONSE_ACCEPT : GTK_RESPONSE_CANCEL);
108 
109  gint result = gtk_dialog_run(GTK_DIALOG(dialog));
110 
111  gtk_widget_destroy (dialog);
112  g_free(buffer);
113 
114  return result == GTK_RESPONSE_ACCEPT;
115 }
116 
117 /********************************************************************\
118  * gnc_verify_dialog *
119  * display a message, and asks the user to press "Yes" or "No" *
120  * *
121  * NOTE: This function does not return until the dialog is closed *
122  * *
123  * Args: parent - the parent window *
124  * yes_is_default - If true, "Yes" is default, *
125  * "No" is the default button. *
126  * format - the format string for the message to display *
127  * This is a standard 'printf' style string. *
128  * args - a pointer to the first argument for the format *
129  * string. *
130 \********************************************************************/
131 gboolean
132 gnc_verify_dialog(GtkWindow *parent, gboolean yes_is_default,
133  const gchar *format, ...)
134 {
135  GtkWidget *dialog;
136  gchar *buffer;
137  gint result;
138  va_list args;
139 
140  if (!parent)
141  parent = gnc_ui_get_main_window (NULL);
142 
143  va_start(args, format);
144  buffer = g_strdup_vprintf(format, args);
145  dialog = gtk_message_dialog_new (parent,
146  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
147  GTK_MESSAGE_QUESTION,
148  GTK_BUTTONS_YES_NO,
149  "%s",
150  buffer);
151  g_free(buffer);
152  va_end(args);
153 
154  if (!parent)
155  gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
156 
157  gtk_dialog_set_default_response(GTK_DIALOG(dialog),
158  (yes_is_default ? GTK_RESPONSE_YES : GTK_RESPONSE_NO));
159  result = gtk_dialog_run(GTK_DIALOG(dialog));
160  gtk_widget_destroy (dialog);
161  return (result == GTK_RESPONSE_YES);
162 }
163 
164 static void
165 gnc_message_dialog_common (GtkWindow *parent, const gchar *format, GtkMessageType msg_type, va_list args)
166 {
167  GtkWidget *dialog = NULL;
168  gchar *buffer;
169 
170  if (!parent)
171  parent = gnc_ui_get_main_window (NULL);
172 
173  buffer = g_strdup_vprintf(format, args);
174  dialog = gtk_message_dialog_new (parent,
175  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
176  msg_type,
177  GTK_BUTTONS_CLOSE,
178  "%s",
179  buffer);
180  g_free(buffer);
181 
182  if (!parent)
183  gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
184 
185  gtk_dialog_run (GTK_DIALOG (dialog));
186  gtk_widget_destroy (dialog);
187 }
188 
189 /********************************************************************\
190  * gnc_info_dialog *
191  * displays an information dialog box *
192  * *
193  * Args: parent - the parent window *
194  * format - the format string for the message to display *
195  * This is a standard 'printf' style string. *
196  * args - a pointer to the first argument for the format *
197  * string. *
198  * Return: none *
199 \********************************************************************/
200 void
201 gnc_info_dialog (GtkWindow *parent, const gchar *format, ...)
202 {
203  va_list args;
204 
205  va_start(args, format);
206  gnc_message_dialog_common (parent, format, GTK_MESSAGE_INFO, args);
207  va_end(args);
208 }
209 
210 
211 
212 /********************************************************************\
213  * gnc_warning_dialog *
214  * displays a warning dialog box *
215  * *
216  * Args: parent - the parent window *
217  * format - the format string for the message to display *
218  * This is a standard 'printf' style string. *
219  * args - a pointer to the first argument for the format *
220  * string. *
221  * Return: none *
222 \********************************************************************/
223 
224 void
225 gnc_warning_dialog (GtkWindow *parent, const gchar *format, ...)
226 {
227  va_list args;
228 
229  va_start(args, format);
230  gnc_message_dialog_common (parent, format, GTK_MESSAGE_WARNING, args);
231  va_end(args);
232 }
233 
234 
235 /********************************************************************\
236  * gnc_error_dialog *
237  * displays an error dialog box *
238  * *
239  * Args: parent - the parent window *
240  * format - the format string for the message to display *
241  * This is a standard 'printf' style string. *
242  * args - a pointer to the first argument for the format *
243  * string. *
244  * Return: none *
245 \********************************************************************/
246 void gnc_error_dialog (GtkWindow* parent, const char* format, ...)
247 {
248  va_list args;
249 
250  va_start(args, format);
251  gnc_message_dialog_common (parent, format, GTK_MESSAGE_ERROR, args);
252  va_end(args);
253 }
254 
255 static void
256 gnc_choose_radio_button_cb(GtkWidget *w, gpointer data)
257 {
258  int *result = data;
259 
260  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
261  *result = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), INDEX_LABEL));
262 }
263 
264 /********************************************************************
265  gnc_choose_radio_option_dialog
266 
267  display a group of radio_buttons and return the index of
268  the selected one
269 */
270 
271 int
272 gnc_choose_radio_option_dialog(GtkWidget *parent,
273  const char *title,
274  const char *msg,
275  const char *button_name,
276  int default_value,
277  GList *radio_list)
278 {
279  int radio_result = 0; /* initial selected value is first one */
280  GtkWidget *vbox;
281  GtkWidget *main_vbox;
282  GtkWidget *label;
283  GtkWidget *radio_button;
284  GtkWidget *dialog;
285  GtkWidget *dvbox;
286  GSList *group = NULL;
287  GList *node;
288  int i;
289 
290  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
291  gtk_box_set_homogeneous (GTK_BOX (main_vbox), FALSE);
292  gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 6);
293  gtk_widget_show(main_vbox);
294 
295  label = gtk_label_new(msg);
296  gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
297  gtk_box_pack_start(GTK_BOX(main_vbox), label, FALSE, FALSE, 0);
298  gtk_widget_show(label);
299 
300  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
301  gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE);
302  gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
303  gtk_container_add(GTK_CONTAINER(main_vbox), vbox);
304  gtk_widget_show(vbox);
305 
306  for (node = radio_list, i = 0; node; node = node->next, i++)
307  {
308  radio_button = gtk_radio_button_new_with_mnemonic(group, node->data);
309  group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio_button));
310  gtk_widget_set_halign (GTK_WIDGET(radio_button), GTK_ALIGN_START);
311 
312  if (i == default_value) /* default is first radio button */
313  {
314  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button), TRUE);
315  radio_result = default_value;
316  }
317 
318  gtk_widget_show(radio_button);
319  gtk_box_pack_start(GTK_BOX(vbox), radio_button, FALSE, FALSE, 0);
320  g_object_set_data(G_OBJECT(radio_button), INDEX_LABEL, GINT_TO_POINTER(i));
321  g_signal_connect(radio_button, "clicked",
322  G_CALLBACK(gnc_choose_radio_button_cb),
323  &radio_result);
324  }
325 
326  if (!button_name)
327  button_name = _("_OK");
328  dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW(parent),
329  GTK_DIALOG_DESTROY_WITH_PARENT,
330  _("_Cancel"), GTK_RESPONSE_CANCEL,
331  button_name, GTK_RESPONSE_OK,
332  NULL);
333 
334  /* default to ok */
335  gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
336 
337  dvbox = gtk_dialog_get_content_area (GTK_DIALOG(dialog));
338 
339  gtk_box_pack_start(GTK_BOX(dvbox), main_vbox, TRUE, TRUE, 0);
340 
341  if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
342  radio_result = -1;
343 
344  gtk_widget_destroy (dialog);
345 
346  return radio_result;
347 }
348 
349 static gchar *
350 gnc_input_dialog_internal (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input, gboolean use_entry)
351 {
352  gint result;
353  GtkWidget *view;
354  GtkTextBuffer *buffer;
355  gchar *user_input = NULL;
356  GtkTextIter start, end;
357 
358  /* Create the widgets */
359  GtkWidget* dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
360  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
361  _("_OK"), GTK_RESPONSE_ACCEPT,
362  _("_Cancel"), GTK_RESPONSE_REJECT,
363  NULL);
364  GtkWidget* content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
365 
366  // add a label
367  GtkWidget* label = gtk_label_new (msg);
368  gtk_box_pack_start(GTK_BOX(content_area), label, FALSE, FALSE, 0);
369 
370  // add a textview or an entry.
371  if (use_entry)
372  {
373  view = gtk_entry_new ();
374  gtk_entry_set_text (GTK_ENTRY (view), default_input);
375  }
376  else
377  {
378  view = gtk_text_view_new ();
379  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD_CHAR);
380  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
381  gtk_text_buffer_set_text (buffer, default_input, -1);
382  }
383  gtk_box_pack_start(GTK_BOX(content_area), view, TRUE, TRUE, 0);
384 
385  // run the dialog
386  gtk_widget_show_all (dialog);
387  result = gtk_dialog_run (GTK_DIALOG (dialog));
388 
389  if (result != GTK_RESPONSE_REJECT)
390  {
391  if (use_entry)
392  user_input = g_strdup (gtk_entry_get_text ((GTK_ENTRY (view))));
393  else
394  {
395  gtk_text_buffer_get_start_iter (buffer, &start);
396  gtk_text_buffer_get_end_iter (buffer, &end);
397  user_input = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
398  }
399  }
400 
401  gtk_widget_destroy (dialog);
402 
403  return user_input;
404 }
405 
406 /********************************************************************\
407  * gnc_input_dialog *
408  * simple convenience dialog to get a single value from the user *
409  * user may choose between "Ok" and "Cancel" *
410  * *
411  * NOTE: This function does not return until the dialog is closed *
412  * *
413  * Args: parent - the parent window or NULL *
414  * title - the title of the dialog *
415  * msg - the message to display *
416  * default_input - will be displayed as default input *
417  * Return: the input (text) the user entered, if pressed "Ok" *
418  * NULL, if pressed "Cancel" *
419  \********************************************************************/
420 gchar *
421 gnc_input_dialog (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input)
422 {
423  return gnc_input_dialog_internal (parent, title, msg, default_input, FALSE);
424 }
425 
426 /********************************************************************\
427  * gnc_input_dialog_with_entry *
428  * Similar to gnc_input_dialog but use a single line entry widget *
429  * user may choose between "Ok" and "Cancel" *
430  \********************************************************************/
431 gchar *
432 gnc_input_dialog_with_entry (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input)
433 {
434  return gnc_input_dialog_internal (parent, title, msg, default_input, TRUE);
435 }
436 
437 void
438 gnc_info2_dialog (GtkWidget *parent, const gchar *title, const gchar *msg)
439 {
440  GtkWidget *view;
441  GtkTextBuffer *buffer;
442  gint width, height;
443 
444  /* Create the widgets */
445  GtkWidget* dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
446  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
447  _("_OK"), GTK_RESPONSE_ACCEPT,
448  NULL);
449  GtkWidget* content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
450 
451  // add a scroll area
452  GtkWidget* scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
453  gtk_box_pack_start(GTK_BOX(content_area), scrolledwindow, TRUE, TRUE, 0);
454 
455  // add a textview
456  view = gtk_text_view_new ();
457  gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
458  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
459  gtk_text_buffer_set_text (buffer, msg, -1);
460  gtk_container_add (GTK_CONTAINER (scrolledwindow), view);
461 
462  // run the dialog
463  if (parent)
464  {
465  gtk_window_get_size (GTK_WINDOW(parent), &width, &height);
466  gtk_window_set_default_size (GTK_WINDOW(dialog), width, height);
467  }
468  gtk_widget_show_all (dialog);
469  gtk_dialog_run (GTK_DIALOG (dialog));
470  gtk_widget_destroy (dialog);
471 }
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.