GnuCash c935c2f+
Loading...
Searching...
No Matches
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 gnu@gnu.org *
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 "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. */
39static 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
45typedef 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
57void gnc_reset_warnings_select_all_cb (GtkButton *button, gpointer user_data);
58void gnc_reset_warnings_unselect_all_cb (GtkButton *button, gpointer user_data);
59void gnc_reset_warnings_response_cb (GtkDialog *dialog, gint response, gpointer user_data);
60static void gnc_reset_warnings_add_section (RWDialog *rw_dialog,
61 const gchar *section, GtkWidget *box);
62static 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 ****************************************************/
70static void
71gnc_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/***************************/
137static void
138gnc_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
161static void
162gnc_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/***************************/
181void
182gnc_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
214static void
215gnc_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
232void
233gnc_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
241void
242gnc_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 ***********************************************************************/
259static void
260gnc_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 ********************************************************************/
290static void
291gnc_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 ***********************************************************************/
321static gboolean
322show_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 structure");
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 ****************************************************/
347static void
348close_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/***********************************************/
362void
363gnc_reset_warnings_dialog (GtkWindow *parent)
364{
365 RWDialog *rw_dialog;
366 GtkWidget *dialog;
367 GtkBuilder *builder;
368
369 ENTER("");
370 if (gnc_forall_gui_components(DIALOG_RESET_WARNINGS_CM_CLASS,
371 show_handler, NULL))
372 {
373 LEAVE("existing window");
374 return;
375 }
376
377 DEBUG("Opening dialog-reset-warnings.glade:");
378 builder = gtk_builder_new();
379 gnc_builder_add_from_file (builder, "dialog-reset-warnings.glade", "reset_warnings_dialog");
380 dialog = GTK_WIDGET(gtk_builder_get_object (builder, "reset_warnings_dialog"));
381
382 // Set the name for this dialog so it can be easily manipulated with css
383 gtk_widget_set_name (GTK_WIDGET(dialog), "gnc-id-reset-warnings");
384
385 gtk_window_set_transient_for(GTK_WINDOW (dialog), parent);
386
387 rw_dialog = g_new0 (RWDialog, 1);
388 rw_dialog->dialog = dialog;
389 PINFO("rw_dialog %p, dialog %p", rw_dialog, dialog);
390
391 /* Connect the signals */
392 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, rw_dialog);
393
394 DEBUG("permanent");
395 rw_dialog->perm_vbox_label = GTK_WIDGET(gtk_builder_get_object (builder, "perm_vbox_and_label"));
396 rw_dialog->perm_vbox = GTK_WIDGET(gtk_builder_get_object (builder, "perm_vbox"));
397 gnc_reset_warnings_add_section(rw_dialog, GNC_PREFS_GROUP_WARNINGS_PERM, rw_dialog->perm_vbox);
398
399 DEBUG("temporary");
400 rw_dialog->temp_vbox_label = GTK_WIDGET(gtk_builder_get_object (builder, "temp_vbox_and_label"));
401 rw_dialog->temp_vbox = GTK_WIDGET(gtk_builder_get_object (builder, "temp_vbox"));
402 gnc_reset_warnings_add_section(rw_dialog, GNC_PREFS_GROUP_WARNINGS_TEMP, rw_dialog->temp_vbox);
403
404 rw_dialog->buttonbox = GTK_WIDGET(gtk_builder_get_object (builder, "hbuttonbox"));
405
406 rw_dialog->nolabel = GTK_WIDGET(gtk_builder_get_object (builder, "no_warnings"));
407 rw_dialog->applybutton = GTK_WIDGET(gtk_builder_get_object (builder, "applybutton"));
408
409 /* Enable the proper response buttons */
410 gnc_reset_warnings_update_widgets(rw_dialog);
411
412 /* Record the pointer to the rw data structure and clean up after */
413 g_object_set_data_full(G_OBJECT(rw_dialog->dialog), "dialog-structure", rw_dialog, g_free);
414
415 gnc_restore_window_size(GNC_PREFS_GROUP, GTK_WINDOW(rw_dialog->dialog), parent);
416
417 gnc_register_gui_component (DIALOG_RESET_WARNINGS_CM_CLASS,
418 NULL, close_handler, rw_dialog);
419
420 gtk_widget_show(GTK_WIDGET(rw_dialog->dialog));
421
422 g_object_unref(G_OBJECT(builder));
423
424 LEAVE(" ");
425}
All type declarations for the whole Gnucash engine.
Generic api to store and retrieve preferences.
#define PINFO(format, args...)
Print an informational note.
Definition qoflog.h:256
#define DEBUG(format, args...)
Print a debugging message.
Definition qoflog.h:264
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
void gnc_prefs_reset(const gchar *group, const gchar *pref_name)
Reset a preference to its default value in the preferences backend.