29 #include <gdk/gdkkeysyms.h> 30 #include <glib/gi18n.h> 36 #include "dialog-utils.h" 48 static QofLogModule log_module = GNC_MOD_GUI;
50 #define GNC_PREF_LAST_GEOMETRY "last-geometry" 61 gnc_set_label_color(GtkWidget *label, gnc_numeric value)
72 gnc_widget_style_context_remove_class (GTK_WIDGET(label),
"gnc-class-default-color");
73 gnc_widget_style_context_add_class (GTK_WIDGET(label),
"gnc-class-negative-numbers");
77 gnc_widget_style_context_remove_class (GTK_WIDGET(label),
"gnc-class-negative-numbers");
78 gnc_widget_style_context_add_class (GTK_WIDGET(label),
"gnc-class-default-color");
97 gnc_restore_window_size(
const char *group, GtkWindow *window, GtkWindow *parent)
99 gint wpos[2], wsize[2];
104 g_return_if_fail(group != NULL);
105 g_return_if_fail(window != NULL);
106 g_return_if_fail(parent != NULL);
113 if (g_variant_is_of_type (geometry, (
const GVariantType *)
"(iiii)") )
115 GdkWindow *win = gtk_widget_get_window (GTK_WIDGET(parent));
116 GdkRectangle monitor_size;
117 GdkDisplay *display = gdk_window_get_display (win);
120 g_variant_get (geometry,
"(iiii)",
122 &wsize[0], &wsize[1]);
124 mon = gdk_display_get_monitor_at_point (display, wpos[0], wpos[1]);
125 gdk_monitor_get_geometry (mon, &monitor_size);
127 DEBUG(
"monitor left top corner x: %d, y: %d, width: %d, height: %d",
128 monitor_size.x, monitor_size.y, monitor_size.width, monitor_size.height);
129 DEBUG(
"geometry from preferences - group, %s, wpos[0]: %d, wpos[1]: %d, wsize[0]: %d, wsize[1]: %d",
130 group, wpos[0], wpos[1], wsize[0], wsize[1]);
133 if ((wpos[0] != -1) && (wpos[1] != -1))
136 if (wpos[0] - monitor_size.x + wsize[0] > monitor_size.x + monitor_size.width)
137 wpos[0] = monitor_size.x + monitor_size.width - wsize[0];
139 if (wpos[1] - monitor_size.y + wsize[1] > monitor_size.y + monitor_size.height)
140 wpos[1] = monitor_size.y + monitor_size.height - wsize[1];
143 if (wpos[0] < monitor_size.x)
144 wpos[0] = monitor_size.x;
146 if (wpos[1] < monitor_size.y)
147 wpos[1] = monitor_size.y;
149 DEBUG(
"geometry after screen adaption - wpos[0]: %d, wpos[1]: %d, wsize[0]: %d, wsize[1]: %d",
150 wpos[0], wpos[1], wsize[0], wsize[1]);
152 gtk_window_move(window, wpos[0], wpos[1]);
159 gint parent_wpos[2], parent_wsize[2], window_wsize[2];
160 gtk_window_get_position (GTK_WINDOW(parent), &parent_wpos[0], &parent_wpos[1]);
161 gtk_window_get_size (GTK_WINDOW(parent), &parent_wsize[0], &parent_wsize[1]);
162 gtk_window_get_size (GTK_WINDOW(window), &window_wsize[0], &window_wsize[1]);
164 DEBUG(
"parent window - wpos[0]: %d, wpos[1]: %d, wsize[0]: %d, wsize[1]: %d - window size is %dx%d",
165 parent_wpos[0], parent_wpos[1], parent_wsize[0], parent_wsize[1],
166 window_wsize[0], window_wsize[1]);
169 if ((window_wsize[0] == 200) && (window_wsize[1] == 200))
170 DEBUG(
"window size not specified, let gtk locate it");
172 gtk_window_move (window, parent_wpos[0] + (parent_wsize[0] - window_wsize[0])/2,
173 parent_wpos[1] + (parent_wsize[1] - window_wsize[1])/2);
178 if ((wsize[0] > 0) && (wsize[1] > 0))
180 wsize[0] = MIN(wsize[0], monitor_size.width - 10);
181 wsize[1] = MIN(wsize[1], monitor_size.height - 10);
183 gtk_window_resize(window, wsize[0], wsize[1]);
186 g_variant_unref (geometry);
202 gnc_save_window_size(
const char *group, GtkWindow *window)
204 gint wpos[2], wsize[2];
209 g_return_if_fail(group != NULL);
210 g_return_if_fail(window != NULL);
215 gtk_window_get_position(GTK_WINDOW(window), &wpos[0], &wpos[1]);
216 gtk_window_get_size(GTK_WINDOW(window), &wsize[0], &wsize[1]);
218 DEBUG(
"save geometry - wpos[0]: %d, wpos[1]: %d, wsize[0]: %d, wsize[1]: %d",
219 wpos[0], wpos[1], wsize[0], wsize[1]);
221 geometry = g_variant_new (
"(iiii)", wpos[0], wpos[1],
237 gnc_window_adjust_for_screen(GtkWindow * window)
242 GdkRectangle monitor_size;
252 g_return_if_fail(GTK_IS_WINDOW(window));
253 if (gtk_widget_get_window (GTK_WIDGET(window)) == NULL)
256 win = gtk_widget_get_window (GTK_WIDGET(window));
257 display = gdk_window_get_display (win);
259 gtk_window_get_position(GTK_WINDOW(window), &wpos[0], &wpos[1]);
260 gtk_window_get_size(GTK_WINDOW(window), &width, &height);
262 mon = gdk_display_get_monitor_at_point (display, wpos[0], wpos[1]);
263 gdk_monitor_get_geometry (mon, &monitor_size);
265 DEBUG(
"monitor width is %d, height is %d; wwindow width is %d, height is %d",
266 monitor_size.width, monitor_size.height, width, height);
268 if ((width <= monitor_size.width) && (height <= monitor_size.height))
272 if (wpos[0] - monitor_size.x + width > monitor_size.x + monitor_size.width)
273 wpos[0] = monitor_size.x + monitor_size.width - width;
275 if (wpos[1] - monitor_size.y + height > monitor_size.y + monitor_size.height)
276 wpos[1] = monitor_size.y + monitor_size.height - height;
279 if (wpos[0] < monitor_size.x)
280 wpos[0] = monitor_size.x;
282 if (wpos[1] < monitor_size.y)
283 wpos[1] = monitor_size.y;
285 DEBUG(
"move window to position %d, %d", wpos[0], wpos[1]);
287 gtk_window_move(window, wpos[0], wpos[1]);
290 width = MIN(width, monitor_size.width - 10);
291 height = MIN(height, monitor_size.height - 10);
293 DEBUG(
"resize window to width %d, height %d", width, height);
295 gtk_window_resize(GTK_WINDOW(window), width, height);
296 gtk_widget_queue_resize(GTK_WIDGET(window));
309 gnc_label_set_alignment (GtkWidget *widget, gfloat xalign, gfloat yalign)
311 gtk_label_set_xalign (GTK_LABEL (widget), xalign);
312 gtk_label_set_yalign (GTK_LABEL (widget), yalign);
322 gnc_tree_view_get_grid_lines_pref (
void)
324 GtkTreeViewGridLines grid_lines;
325 gboolean h_lines =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_GRID_LINES_HORIZONTAL);
326 gboolean v_lines =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_GRID_LINES_VERTICAL);
331 grid_lines = GTK_TREE_VIEW_GRID_LINES_BOTH;
333 grid_lines = GTK_TREE_VIEW_GRID_LINES_HORIZONTAL;
336 grid_lines = GTK_TREE_VIEW_GRID_LINES_VERTICAL;
338 grid_lines = GTK_TREE_VIEW_GRID_LINES_NONE;
350 gnc_widget_style_context_add_class (GtkWidget *widget,
const char *gnc_class)
352 GtkStyleContext *context = gtk_widget_get_style_context (widget);
353 gtk_style_context_add_class (context, gnc_class);
364 gnc_widget_style_context_remove_class (GtkWidget *widget,
const char *gnc_class)
366 GtkStyleContext *context = gtk_widget_get_style_context (widget);
368 if (gtk_style_context_has_class (context, gnc_class))
369 gtk_style_context_remove_class (context, gnc_class);
381 gnc_draw_arrow_cb (GtkWidget *widget, cairo_t *cr, gpointer direction)
383 GtkStyleContext *context = gtk_widget_get_style_context (widget);
384 gint width = gtk_widget_get_allocated_width (widget);
385 gint height = gtk_widget_get_allocated_height (widget);
388 gtk_render_background (context, cr, 0, 0, width, height);
389 gtk_style_context_add_class (context, GTK_STYLE_CLASS_ARROW);
391 size = MIN(width / 2, height / 2);
393 if (GPOINTER_TO_INT(direction) == 0)
394 gtk_render_arrow (context, cr, 0,
395 (width - size)/2, (height - size)/2, size);
397 gtk_render_arrow (context, cr, G_PI,
398 (width - size)/2, (height - size)/2, size);
405 gnc_gdate_in_valid_range (GDate *test_date, gboolean warn)
408 GDate *max_date = g_date_new_dmy (1,1,10000);
410 gboolean ret = FALSE;
411 gboolean max_date_ok = FALSE;
412 gboolean min_date_ok = FALSE;
414 if (use_autoreadonly)
417 min_date = g_date_new_dmy (1,1,1400);
420 if (g_date_compare (max_date, test_date) > 0)
424 if (g_date_compare (min_date, test_date) <= 0)
427 if (use_autoreadonly && warn)
430 ret = min_date_ok & max_date_ok;
435 gchar *dialog_msg = _(
"The entered date is out of the range " 436 "01/01/1400 - 31/12/9999, resetting to this year");
437 gchar *dialog_title = _(
"Date out of range");
443 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
445 gtk_dialog_run (GTK_DIALOG(dialog));
446 gtk_widget_destroy (dialog);
448 g_date_free (max_date);
449 g_date_free (min_date);
455 gnc_handle_date_accelerator (GdkEventKey *event,
457 const char *date_str)
461 g_return_val_if_fail (event != NULL, FALSE);
462 g_return_val_if_fail (tm != NULL, FALSE);
463 g_return_val_if_fail (date_str != NULL, FALSE);
465 if (event->type != GDK_KEY_PRESS)
468 if ((tm->tm_mday <= 0) || (tm->tm_mon == -1) || (tm->tm_year == -1))
472 if (!g_date_valid_dmy (tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900))
475 g_date_set_dmy (&gdate,
484 switch (event->keyval)
489 case GDK_KEY_semicolon:
490 if (event->state & GDK_SHIFT_MASK)
491 g_date_add_days (&gdate, 7);
492 else if (event->state & GDK_MOD1_MASK)
493 g_date_add_months (&gdate, 1);
494 else if (event->state & GDK_CONTROL_MASK)
495 g_date_add_years (&gdate, 1);
497 g_date_add_days (&gdate, 1);
499 if (gnc_gdate_in_valid_range (&gdate, FALSE))
500 g_date_to_struct_tm (&gdate, tm);
504 case GDK_KEY_KP_Subtract:
505 case GDK_KEY_underscore:
516 uc = g_utf8_get_char (c);
519 c = g_utf8_next_char (c);
526 if (event->state & GDK_SHIFT_MASK)
527 g_date_subtract_days (&gdate, 7);
528 else if (event->state & GDK_MOD1_MASK)
529 g_date_subtract_months (&gdate, 1);
530 else if (event->state & GDK_CONTROL_MASK)
531 g_date_subtract_years (&gdate, 1);
533 g_date_subtract_days (&gdate, 1);
535 if (gnc_gdate_in_valid_range (&gdate, FALSE))
536 g_date_to_struct_tm (&gdate, tm);
549 if (event->state & (GDK_MODIFIER_INTENT_DEFAULT_MOD_MASK))
553 switch (event->keyval)
555 case GDK_KEY_braceright:
556 case GDK_KEY_bracketright:
558 g_date_add_months (&gdate, 1);
561 case GDK_KEY_braceleft:
562 case GDK_KEY_bracketleft:
564 g_date_subtract_months (&gdate, 1);
570 g_date_set_day (&gdate, 1);
576 g_date_set_day (&gdate, 1);
577 g_date_add_months (&gdate, 1);
578 g_date_subtract_days (&gdate, 1);
584 g_date_set_day (&gdate, 1);
585 g_date_set_month (&gdate, 1);
591 g_date_set_day (&gdate, 1);
592 g_date_set_month (&gdate, 1);
593 g_date_add_years (&gdate, 1);
594 g_date_subtract_days (&gdate, 1);
606 if (gnc_gdate_in_valid_range (&gdate, FALSE))
607 g_date_to_struct_tm (&gdate, tm);
617 GModule *allsymbols = NULL;
626 gnc_builder_add_from_file (GtkBuilder *builder,
const char *filename,
const char *root)
628 GError* error = NULL;
630 gchar *gnc_builder_dir;
633 g_return_val_if_fail (builder != NULL, FALSE);
634 g_return_val_if_fail (filename != NULL, FALSE);
635 g_return_val_if_fail (root != NULL, FALSE);
637 gnc_builder_dir = gnc_path_get_gtkbuilderdir ();
638 fname = g_build_filename(gnc_builder_dir, filename, (
char *)NULL);
639 g_free (gnc_builder_dir);
642 gchar *localroot = g_strdup(root);
643 gchar *objects[] = { localroot, NULL };
644 result = gtk_builder_add_objects_from_file (builder, fname, objects, &error);
647 PWARN (
"Couldn't load builder file: %s", error->message);
648 g_error_free (error);
663 gnc_builder_connect_full_func(GtkBuilder *builder,
664 GObject *signal_object,
665 const gchar *signal_name,
666 const gchar *handler_name,
667 GObject *connect_object,
672 GCallback *p_func = &func;
674 if (allsymbols == NULL)
677 allsymbols = g_module_open(NULL, 0);
680 if (!g_module_symbol(allsymbols, handler_name, (gpointer *)p_func))
684 func = dlsym(RTLD_DEFAULT, handler_name);
690 PWARN(
"ggaff: could not find signal handler '%s'.", handler_name);
696 g_signal_connect_object (signal_object, signal_name, func,
697 connect_object, flags);
699 g_signal_connect_data(signal_object, signal_name, func,
700 user_data, NULL , flags);
708 gnc_gtk_dialog_add_button (GtkWidget *dialog,
const gchar *label,
const gchar *icon_name, guint response)
712 button = gtk_button_new_with_mnemonic(label);
717 image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON);
718 gtk_button_set_image (GTK_BUTTON(button), image);
719 g_object_set (button,
"always-show-image", TRUE, NULL);
721 g_object_set (button,
"can-default", TRUE, NULL);
722 gtk_widget_show_all(button);
723 gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button, response);
727 gnc_perm_button_cb (GtkButton *perm, gpointer user_data)
729 gboolean perm_active;
731 perm_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(perm));
732 gtk_widget_set_sensitive(user_data, !perm_active);
736 gnc_dialog_run (GtkDialog *dialog,
const gchar *pref_name)
738 GtkWidget *perm, *temp;
752 if (GTK_IS_MESSAGE_DIALOG(dialog))
755 g_object_get(dialog,
"message-type", &type, (gchar*)NULL);
756 ask = (type == GTK_MESSAGE_QUESTION || type == GTK_MESSAGE_WARNING);
758 perm = gtk_check_button_new_with_mnemonic
760 ? _(
"Remember and don't _ask me again.")
761 : _(
"Don't _tell me again."));
762 temp = gtk_check_button_new_with_mnemonic
764 ? _(
"Remember and don't ask me again this _session.")
765 : _(
"Don't tell me again this _session."));
766 gtk_widget_show(perm);
767 gtk_widget_show(temp);
768 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (dialog)), perm, TRUE, TRUE, 0);
769 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (dialog)), temp, TRUE, TRUE, 0);
770 g_signal_connect(perm,
"clicked", G_CALLBACK(gnc_perm_button_cb), temp);
773 response = gtk_dialog_run(dialog);
774 if ((response == GTK_RESPONSE_NONE) || (response == GTK_RESPONSE_DELETE_EVENT))
776 return GTK_RESPONSE_CANCEL;
779 if (response != GTK_RESPONSE_CANCEL)
782 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(perm)))
786 else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(temp)))
799 gnc_new_book_option_display (GtkWidget *parent)
802 gint result = GTK_RESPONSE_HELP;
805 GTK_WINDOW (parent));
809 while (result == GTK_RESPONSE_HELP)
811 result = gtk_dialog_run(GTK_DIALOG(window));
819 gnc_get_negative_color (
void)
822 GtkWidget *label = gtk_label_new (
"Color");
823 GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET(label));
824 gtk_style_context_add_class (context,
"gnc-class-negative-numbers");
825 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
827 return gdk_rgba_to_string (&color);
831 gnc_owner_window_set_title (GtkWindow *window,
const char *header,
832 GtkWidget *owner_entry, GtkWidget *id_entry)
834 const char *name = gtk_entry_get_text (GTK_ENTRY (owner_entry));
835 if (!name || *name ==
'\0')
836 name = _(
"<No name>");
838 const char *
id = gtk_entry_get_text (GTK_ENTRY (id_entry));
840 char *title = (
id && *id) ?
841 g_strdup_printf (
"%s - %s (%s)", header, name,
id) :
842 g_strdup_printf (
"%s - %s", header, name);
844 gtk_window_set_title (window, title);
gchar dateSeparator(void)
dateSeparator Return the field separator for the current date format
gboolean gnc_prefs_set_value(const gchar *group, const gchar *pref_name, GVariant *value)
Store an arbitrary combination of values into the preferences backend.
Date and Time handling routines.
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
utility functions for the GnuCash UI
#define DEBUG(format, args...)
Print a debugging message.
void gnc_gdate_set_today(GDate *gd)
Set a GDate to the current day.
gboolean gnc_prefs_set_int(const gchar *group, const gchar *pref_name, gint value)
Store an integer value into the preferences backend.
GtkWidget * gnc_book_options_dialog_cb(gboolean modal, gchar *title, GtkWindow *parent)
Opens the Book Options dialog.
#define ENTER(format, args...)
Print a function entry debugging message.
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
Functions for adding content to a window.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
#define PWARN(format, args...)
Log a warning.
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
Returns the GDate that is the threshold for auto-read-only.
All type declarations for the whole Gnucash engine.
GVariant * gnc_prefs_get_value(const gchar *group, const gchar *pref_name)
Get an arbitrary combination of values from the preferences backend.
Generic api to store and retrieve preferences.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
#define LEAVE(format, args...)
Print a function exit debugging message.
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Returns TRUE if the auto-read-only feature should be used, otherwise FALSE.
Commodity handling public routines.