GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dialog-reset-warnings.c
1 /***********************************************************************
2  * dialog-reset-warnings.c -- "Resert Warnings" dialog *
3  * Copyright (C) 2005 David Hampton *
4  * Copyright (C) 2011 Robert Fewell *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with this program; if not, contact: *
18  * *
19  * Free Software Foundation Voice: +1-617-542-5942 *
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21  * Boston, MA 02110-1301, USA [email protected] *
22  * *
23  **********************************************************************/
24 
25 #include "config.h"
26 
27 #include <glib/gi18n.h>
28 #include <gtk/gtk.h>
29 
30 #include "dialog-utils.h"
31 #include "gnc-engine.h"
32 #include "gnc-prefs.h"
33 #include "gnc-ui.h"
34 #include "gnome-utils/gnc-warnings.h"
35 #include "gnc-component-manager.h"
36 #include "dialog-reset-warnings.h"
37 
38 /* This static indicates the debugging module that this .o belongs to. */
39 static QofLogModule log_module = GNC_MOD_PREFS;
40 
41 #define GNC_PREFS_GROUP "dialogs.reset-warnings"
42 #define DIALOG_RESET_WARNINGS_CM_CLASS "reset-warnings"
43 #define TIPS_STRING "tips"
44 
45 typedef struct
46 {
47  GtkWidget *dialog;
48  GtkWidget *perm_vbox_label;
49  GtkWidget *perm_vbox;
50  GtkWidget *temp_vbox_label;
51  GtkWidget *temp_vbox;
52  GtkWidget *buttonbox;
53  GtkWidget *nolabel;
54  GtkWidget *applybutton;
55 } RWDialog;
56 
57 void gnc_reset_warnings_select_all_cb (GtkButton *button, gpointer user_data);
58 void gnc_reset_warnings_unselect_all_cb (GtkButton *button, gpointer user_data);
59 void gnc_reset_warnings_response_cb (GtkDialog *dialog, gint response, gpointer user_data);
60 static void gnc_reset_warnings_add_section (RWDialog *rw_dialog,
61  const gchar *section, GtkWidget *box);
62 static void gnc_reset_warnings_update_widgets (RWDialog *rw_dialog);
63 
64 
65 /****************************************************
66  * Update the Dialog Widgets
67  * @internal
68  * @param rw_dialog structure.
69  ****************************************************/
70 static void
71 gnc_reset_warnings_update_widgets (RWDialog *rw_dialog)
72 {
73  GList *list, *tmp;
74  gboolean any = FALSE, checked = FALSE;
75 
76  ENTER("rw_dialog %p", rw_dialog);
77 
78  list = gtk_container_get_children(GTK_CONTAINER(rw_dialog->perm_vbox));
79  if (list)
80  {
81  gtk_widget_show_all(rw_dialog->perm_vbox_label);
82  for (tmp = list; tmp; tmp = g_list_next(tmp))
83  {
84  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tmp->data)))
85  {
86  checked = TRUE;
87  break;
88  }
89  }
90  g_list_free(list);
91  any = TRUE;
92  }
93  else
94  {
95  gtk_widget_hide(rw_dialog->perm_vbox_label);
96  }
97 
98  list = gtk_container_get_children(GTK_CONTAINER(rw_dialog->temp_vbox));
99  if (list)
100  {
101  gtk_widget_show_all(rw_dialog->temp_vbox_label);
102  for (tmp = list; tmp; tmp = g_list_next(tmp))
103  {
104  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tmp->data)))
105  {
106  checked = TRUE;
107  break;
108  }
109  }
110  g_list_free(list);
111  any = TRUE;
112  }
113  else
114  {
115  gtk_widget_hide(rw_dialog->temp_vbox_label);
116  }
117 
118  if (any)
119  {
120  gtk_widget_show(rw_dialog->buttonbox);
121  gtk_widget_hide(rw_dialog->nolabel);
122  gtk_widget_set_sensitive(rw_dialog->applybutton, checked);
123  }
124  else
125  {
126  gtk_widget_hide(rw_dialog->buttonbox);
127  gtk_widget_show(rw_dialog->nolabel);
128  gtk_widget_set_sensitive(rw_dialog->applybutton, FALSE);
129  }
130  LEAVE(" ");
131 }
132 
133 
134 /***************************/
135 /* Helper functions */
136 /***************************/
137 static void
138 gnc_reset_warnings_apply_one (GtkWidget *widget,
139  GtkDialog *dialog)
140 {
141  const gchar *pref = NULL;
142  const gchar *prefs_group = NULL;
143 
144  ENTER("widget %p, dialog %p", widget, dialog);
145 
146  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
147  {
148  LEAVE("not active");
149  return;
150  }
151 
152  pref = gtk_widget_get_name(widget);
153  prefs_group = g_object_get_data (G_OBJECT (widget), "prefs-group");
154  if (prefs_group)
155  gnc_prefs_reset (prefs_group, pref);
156  gtk_widget_destroy(widget);
157  LEAVE(" ");
158 }
159 
160 
161 static void
162 gnc_reset_warnings_apply_changes (RWDialog *rw_dialog)
163 {
164  ENTER("rw_dialog %p", rw_dialog);
165 
166  gtk_container_foreach(GTK_CONTAINER(rw_dialog->perm_vbox),
167  (GtkCallback)gnc_reset_warnings_apply_one,
168  rw_dialog->dialog);
169 
170  gtk_container_foreach(GTK_CONTAINER(rw_dialog->temp_vbox),
171  (GtkCallback)gnc_reset_warnings_apply_one,
172  rw_dialog->dialog);
173  gnc_reset_warnings_update_widgets(rw_dialog);
174  LEAVE(" ");
175 }
176 
177 
178 /***************************/
179 /* Dialog Callbacks */
180 /***************************/
181 void
182 gnc_reset_warnings_response_cb (GtkDialog *dialog,
183  gint response,
184  gpointer user_data)
185 {
186  RWDialog *rw_dialog = user_data;
187 
188  ENTER("dialog %p, response %d, user_data %p", dialog, response, user_data);
189 
190  switch (response)
191  {
192  case GTK_RESPONSE_APPLY:
193  gnc_reset_warnings_apply_changes(rw_dialog);
194  break;
195 
196  case GTK_RESPONSE_OK:
197  gnc_reset_warnings_apply_changes(rw_dialog);
198  gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(rw_dialog->dialog));
199  gnc_unregister_gui_component_by_data(DIALOG_RESET_WARNINGS_CM_CLASS,
200  rw_dialog);
201  gtk_widget_destroy(GTK_WIDGET(rw_dialog->dialog));
202  break;
203 
204  default:
205  gnc_unregister_gui_component_by_data(DIALOG_RESET_WARNINGS_CM_CLASS,
206  rw_dialog);
207  gtk_widget_destroy(GTK_WIDGET(rw_dialog->dialog));
208  break;
209  }
210  LEAVE("");
211 }
212 
213 
214 static void
215 gnc_reset_warnings_select_common (RWDialog *rw_dialog,
216  gboolean selected)
217 {
218  ENTER("rw_dialog %p, selected %d", rw_dialog, selected);
219 
220  gtk_container_foreach(GTK_CONTAINER(rw_dialog->perm_vbox),
221  (GtkCallback)gtk_toggle_button_set_active,
222  GINT_TO_POINTER(selected));
223 
224  gtk_container_foreach(GTK_CONTAINER(rw_dialog->temp_vbox),
225  (GtkCallback)gtk_toggle_button_set_active,
226  GINT_TO_POINTER(selected));
227  gnc_reset_warnings_update_widgets(rw_dialog);
228  LEAVE(" ");
229 }
230 
231 
232 void
233 gnc_reset_warnings_select_all_cb (GtkButton *button,
234  gpointer user_data)
235 {
236  RWDialog *rw_dialog = user_data;
237  gnc_reset_warnings_select_common(rw_dialog, TRUE);
238 }
239 
240 
241 void
242 gnc_reset_warnings_unselect_all_cb (GtkButton *button,
243  gpointer user_data)
244 {
245  RWDialog *rw_dialog = user_data;
246  gnc_reset_warnings_select_common(rw_dialog, FALSE);
247 }
248 
249 
250 /***********************************************************************
251  * This call back function adds a warning to the correct dialog box.
252  *
253  * @internal
254  * @param rw_dialog, the data structure
255  * @param prefs_group the preference group that holds the warning status.
256  * @param warning a record with details for one warning.
257  * @param box, the required dialog box to update.
258  ***********************************************************************/
259 static void
260 gnc_reset_warnings_add_one (RWDialog *rw_dialog, const gchar *prefs_group,
261  const GncWarningSpec *warning, GtkWidget *box)
262 {
263  GtkWidget *checkbox;
264 
265  ENTER("rw_dialog %p, warning %p, box %p", rw_dialog, warning, box);
266 
267  checkbox = gtk_check_button_new_with_label( _(warning->warn_desc ? warning->warn_desc : warning->warn_name));
268  if (warning->warn_long_desc)
269  gtk_widget_set_tooltip_text(checkbox, _(warning->warn_long_desc));
270 
271  gtk_widget_set_name(checkbox, warning->warn_name);
272  g_object_set_data_full (G_OBJECT (checkbox), "prefs-group", g_strdup(prefs_group),
273  (GDestroyNotify) g_free);
274  g_signal_connect_swapped(G_OBJECT(checkbox), "toggled",
275  (GCallback)gnc_reset_warnings_update_widgets, rw_dialog);
276  gtk_box_pack_start(GTK_BOX(box), checkbox, TRUE, TRUE, 0);
277  LEAVE(" ");
278 }
279 
280 
281 /********************************************************************
282  * Add all warnings found in the given preference group
283  * to the dialog box.
284  *
285  * @internal
286  * @param The reset warnings data structure
287  * @param The preference group.
288  * @param The required dialog box to update.
289  ********************************************************************/
290 static void
291 gnc_reset_warnings_add_section (RWDialog *rw_dialog, const gchar *prefs_group, GtkWidget *box)
292 {
293  const GncWarningSpec *warning = gnc_get_warnings();
294  gint i = 0;
295 
296  ENTER("rw_dialog %p, section %s, box %p", rw_dialog, prefs_group, box);
297 
298  for (i = 0; warning[i].warn_name; i++)
299  {
300  if (gnc_prefs_get_int(prefs_group, warning[i].warn_name) != 0)
301  {
302  gnc_reset_warnings_add_one(rw_dialog, prefs_group, &warning[i], box);
303  }
304  }
305 
306  LEAVE(" ");
307 }
308 
309 
310 /***********************************************************************
311  * Raise the rw dialog to the top of the window stack. This
312  * function is called if the user attempts to create a second rw
313  * dialog.
314  *
315  * @internal
316  * @param class_name Unused.
317  * @param component_id Unused.
318  * @param user_data A pointer to the rw structure.
319  * @param iter_data Unused.
320  ***********************************************************************/
321 static gboolean
322 show_handler (const char *class_name, gint component_id,
323  gpointer user_data, gpointer iter_data)
324 {
325  RWDialog *rw_dialog = user_data;
326 
327  ENTER(" ");
328  if (!rw_dialog)
329  {
330  LEAVE("no data strucure");
331  return(FALSE);
332  }
333 
334  ENTER(" ");
335  gtk_window_present(GTK_WINDOW(rw_dialog->dialog));
336  LEAVE(" ");
337 
338  return(TRUE);
339 }
340 
341 
342 /****************************************************
343  * Close the reset warnings dialog.
344  * @internal
345  * @param user_data A pointer to the rw structure.
346  ****************************************************/
347 static void
348 close_handler (gpointer user_data)
349 {
350  RWDialog *rw_dialog = user_data;
351 
352  ENTER(" ");
353  gnc_unregister_gui_component_by_data(DIALOG_RESET_WARNINGS_CM_CLASS, rw_dialog);
354  gtk_widget_destroy(rw_dialog->dialog);
355  LEAVE(" ");
356 }
357 
358 
359 /***********************************************/
360 /* Create the Reset Warnings Dialog */
361 /***********************************************/
362 void
363 gnc_reset_warnings_dialog (GtkWindow *parent)
364 {
365  RWDialog *rw_dialog;
366  GtkWidget *dialog;
367  GtkBuilder *builder;
368 
369  rw_dialog = g_new0 (RWDialog, 1);
370 
371  ENTER("");
372  if (gnc_forall_gui_components(DIALOG_RESET_WARNINGS_CM_CLASS,
373  show_handler, NULL))
374  {
375  LEAVE("existing window");
376  return;
377  }
378 
379  DEBUG("Opening dialog-reset-warnings.glade:");
380  builder = gtk_builder_new();
381  gnc_builder_add_from_file (builder, "dialog-reset-warnings.glade", "Reset Warnings");
382  dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Reset Warnings"));
383 
384  gtk_window_set_transient_for(GTK_WINDOW (dialog), parent);
385 
386  rw_dialog->dialog = dialog;
387  PINFO("rw_dialog %p, dialog %p", rw_dialog, dialog);
388 
389  /* Connect the signals */
390  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, rw_dialog);
391 
392  DEBUG("permanent");
393  rw_dialog->perm_vbox_label = GTK_WIDGET(gtk_builder_get_object (builder, "perm_vbox_and_label"));
394  rw_dialog->perm_vbox = GTK_WIDGET(gtk_builder_get_object (builder, "perm_vbox"));
395  gnc_reset_warnings_add_section(rw_dialog, GNC_PREFS_GROUP_WARNINGS_PERM, rw_dialog->perm_vbox);
396 
397  DEBUG("temporary");
398  rw_dialog->temp_vbox_label = GTK_WIDGET(gtk_builder_get_object (builder, "temp_vbox_and_label"));
399  rw_dialog->temp_vbox = GTK_WIDGET(gtk_builder_get_object (builder, "temp_vbox"));
400  gnc_reset_warnings_add_section(rw_dialog, GNC_PREFS_GROUP_WARNINGS_TEMP, rw_dialog->temp_vbox);
401 
402  rw_dialog->buttonbox = GTK_WIDGET(gtk_builder_get_object (builder, "hbuttonbox"));
403 
404  rw_dialog->nolabel = GTK_WIDGET(gtk_builder_get_object (builder, "no_warnings"));
405  rw_dialog->applybutton = GTK_WIDGET(gtk_builder_get_object (builder, "applybutton"));
406 
407  /* Enable the proper response buttons */
408  gnc_reset_warnings_update_widgets(rw_dialog);
409 
410  /* Record the pointer to the rw data structure and clean up after */
411  g_object_set_data_full(G_OBJECT(rw_dialog->dialog), "dialog-structure", rw_dialog, g_free);
412 
413  gnc_restore_window_size(GNC_PREFS_GROUP, GTK_WINDOW(rw_dialog->dialog));
414 
415  gnc_register_gui_component (DIALOG_RESET_WARNINGS_CM_CLASS,
416  NULL, close_handler, rw_dialog);
417 
418  gtk_widget_show(GTK_WIDGET(rw_dialog->dialog));
419 
420  g_object_unref(G_OBJECT(builder));
421 
422  LEAVE(" ");
423 }
#define PINFO(format, args...)
Definition: qoflog.h:249
#define DEBUG(format, args...)
Definition: qoflog.h:255
void gnc_prefs_reset(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:366
#define ENTER(format, args...)
Definition: qoflog.h:261
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Definition: gnc-prefs.c:206
All type declarations for the whole Gnucash engine.
Generic api to store and retrieve preferences.
#define LEAVE(format, args...)
Definition: qoflog.h:271
const gchar * QofLogModule
Definition: qofid.h:89