Merge remote-tracking branch 'origin/maint'

This commit is contained in:
Christopher Lam 2019-11-19 23:07:10 +08:00
commit 21f053398f
34 changed files with 1023 additions and 894 deletions

View File

@ -40,54 +40,55 @@
#include "gnc-date.h" #include "gnc-date.h"
enum { enum {
PROP_0, PROP_0,
PROP_USE_BUTTONS, PROP_USE_BUTTONS,
}; };
static void gcrd_init (GncCellRendererDate *date); static void gcrd_init (GncCellRendererDate *date);
static void gcrd_class_init (GncCellRendererDateClass *klass); static void gcrd_class_init (GncCellRendererDateClass *klass);
static void gcrd_set_property (GObject *object, static void gcrd_set_property (GObject *object,
guint param_id, guint param_id,
const GValue *value, const GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gcrd_get_property (GObject *object, static void gcrd_get_property (GObject *object,
guint param_id, guint param_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gcrd_today_clicked (GtkWidget *button, static void gcrd_today_clicked (GtkWidget *button,
GncCellRendererDate *cell); GncCellRendererDate *cell);
static void gcrd_selected_double_click (GtkWidget *calendar, static void gcrd_selected_double_click (GtkWidget *calendar,
GncCellRendererDate *cell); GncCellRendererDate *cell);
static void gcrd_cancel_clicked (GtkWidget *popup_window, static void gcrd_cancel_clicked (GtkWidget *popup_window,
GncCellRendererDate *cell); GncCellRendererDate *cell);
static void gcrd_ok_clicked (GtkWidget *popup_window, static void gcrd_ok_clicked (GtkWidget *popup_window,
GncCellRendererDate *cell); GncCellRendererDate *cell);
static void gcrd_day_selected (GtkWidget *popup_window, static void gcrd_day_selected (GtkWidget *popup_window,
GncCellRendererDate *cell); GncCellRendererDate *cell);
GtkCellEditable *gcrd_start_editing (GtkCellRenderer *cell, GtkCellEditable *gcrd_start_editing (GtkCellRenderer *cell,
GdkEvent *event, GdkEvent *event,
GtkWidget *widget, GtkWidget *widget,
const gchar *path, const gchar *path,
const GdkRectangle *background_area, const GdkRectangle *background_area,
const GdkRectangle *cell_area, const GdkRectangle *cell_area,
GtkCellRendererState flags); GtkCellRendererState flags);
static void gcrd_show (GncCellRendererPopup *cell, static void gcrd_show (GncCellRendererPopup *cell,
const gchar *path, const gchar *path,
gint x1, gint x1,
gint y1, gint y1,
gint x2, gint x2,
gint y2); gint y2);
static void gcrd_hide (GncCellRendererPopup *cell);
static void gcrd_hide (GncCellRendererPopup *cell);
/* These two functions are used internally */ /* These two functions are used internally */
@ -104,329 +105,318 @@ static GncCellRendererPopupClass *parent_class;
GType GType
gnc_cell_renderer_date_get_type (void) gnc_cell_renderer_date_get_type (void)
{ {
static GType cell_text_type = 0; static GType cell_text_type = 0;
if (!cell_text_type) { if (!cell_text_type) {
static const GTypeInfo cell_text_info = { static const GTypeInfo cell_text_info = {
sizeof (GncCellRendererDateClass), sizeof (GncCellRendererDateClass),
NULL, /* base_init */ NULL, /* base_init */
NULL, /* base_finalize */ NULL, /* base_finalize */
(GClassInitFunc) gcrd_class_init, (GClassInitFunc) gcrd_class_init,
NULL, /* class_finalize */ NULL, /* class_finalize */
NULL, /* class_data */ NULL, /* class_data */
sizeof (GncCellRendererDate), sizeof (GncCellRendererDate),
0, /* n_preallocs */ 0, /* n_preallocs */
(GInstanceInitFunc) gcrd_init, (GInstanceInitFunc) gcrd_init,
}; };
cell_text_type = g_type_register_static (GNC_TYPE_CELL_RENDERER_POPUP, cell_text_type = g_type_register_static (GNC_TYPE_CELL_RENDERER_POPUP,
"GncCellRendererDate", "GncCellRendererDate",
&cell_text_info, &cell_text_info,
0); 0);
} }
return cell_text_type; return cell_text_type;
} }
static void static void
gcrd_init (GncCellRendererDate *date) gcrd_init (GncCellRendererDate *date)
{ {
GncCellRendererPopup *popup; GncCellRendererPopup *popup;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *button; GtkWidget *button;
popup = GNC_CELL_RENDERER_POPUP (date); popup = GNC_CELL_RENDERER_POPUP(date);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (popup->popup_window), frame); gtk_container_add (GTK_CONTAINER(popup->popup_window), frame);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_OUT);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_box_set_homogeneous (GTK_BOX (vbox), FALSE); gtk_box_set_homogeneous (GTK_BOX(vbox), FALSE);
gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_container_add (GTK_CONTAINER(frame), vbox);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); gtk_container_set_border_width (GTK_CONTAINER(vbox), 6);
date->calendar = gtk_calendar_new ();
popup->focus_window = date->calendar;
gtk_box_pack_start (GTK_BOX (vbox), date->calendar, TRUE, TRUE, 0);
date->button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); date->calendar = gtk_calendar_new ();
gtk_box_set_spacing (GTK_BOX (date->button_box), 6); popup->focus_window = date->calendar;
gtk_box_pack_start (GTK_BOX (vbox), date->button_box, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX(vbox), date->calendar, TRUE, TRUE, 0);
button = gtk_button_new_with_label (_("Cancel")); date->button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (date->button_box), button); gtk_box_set_spacing (GTK_BOX(date->button_box), 6);
g_signal_connect (button, "clicked", gtk_box_pack_start (GTK_BOX(vbox), date->button_box, FALSE, FALSE, 0);
G_CALLBACK (gcrd_cancel_clicked),
date);
date->today_button = gtk_button_new_with_label (_("Today")); button = gtk_button_new_with_label (_("Cancel"));
gtk_container_add (GTK_CONTAINER (date->button_box), date->today_button); gtk_container_add (GTK_CONTAINER(date->button_box), button);
g_signal_connect (date->today_button, "clicked", g_signal_connect (button, "clicked",
G_CALLBACK (gcrd_today_clicked), G_CALLBACK(gcrd_cancel_clicked),
date); date);
button = gtk_button_new_with_label (_("Select")); date->today_button = gtk_button_new_with_label (_("Today"));
gtk_container_add (GTK_CONTAINER (date->button_box), button); gtk_container_add (GTK_CONTAINER(date->button_box), date->today_button);
g_signal_connect (button, "clicked", g_signal_connect (date->today_button, "clicked",
G_CALLBACK (gcrd_ok_clicked), G_CALLBACK(gcrd_today_clicked),
date); date);
g_signal_connect (date->calendar, "day-selected", button = gtk_button_new_with_label (_("Select"));
G_CALLBACK (gcrd_day_selected), gtk_container_add (GTK_CONTAINER(date->button_box), button);
date); g_signal_connect (button, "clicked",
g_signal_connect (date->calendar, "day-selected-double-click", G_CALLBACK(gcrd_ok_clicked),
G_CALLBACK (gcrd_selected_double_click), date);
date);
//Set calendar to show current date when displayed g_signal_connect (date->calendar, "day-selected",
date->time = gnc_time (NULL); G_CALLBACK(gcrd_day_selected),
date);
g_signal_connect (date->calendar, "day-selected-double-click",
G_CALLBACK(gcrd_selected_double_click),
date);
gtk_widget_show_all (frame); //Set calendar to show current date when displayed
date->time = gnc_time (NULL);
gtk_widget_show_all (frame);
} }
static void static void
gcrd_class_init (GncCellRendererDateClass *klass) gcrd_class_init (GncCellRendererDateClass *klass)
{ {
GncCellRendererPopupClass *popup_class; GncCellRendererPopupClass *popup_class;
GtkCellRendererClass *cell_class; GtkCellRendererClass *cell_class;
GObjectClass *gobject_class; GObjectClass *gobject_class;
popup_class = GNC_CELL_RENDERER_POPUP_CLASS (klass); popup_class = GNC_CELL_RENDERER_POPUP_CLASS(klass);
cell_class = GTK_CELL_RENDERER_CLASS (klass); cell_class = GTK_CELL_RENDERER_CLASS(klass);
parent_class = GNC_CELL_RENDERER_POPUP_CLASS (g_type_class_peek_parent (klass)); parent_class = GNC_CELL_RENDERER_POPUP_CLASS(g_type_class_peek_parent (klass));
gobject_class = G_OBJECT_CLASS (klass); gobject_class = G_OBJECT_CLASS(klass);
gobject_class->set_property = gcrd_set_property; gobject_class->set_property = gcrd_set_property;
gobject_class->get_property = gcrd_get_property; gobject_class->get_property = gcrd_get_property;
cell_class->start_editing = gcrd_start_editing; cell_class->start_editing = gcrd_start_editing;
popup_class->show_popup = gcrd_show;
popup_class->hide_popup = gcrd_hide;
g_object_class_install_property ( popup_class->show_popup = gcrd_show;
gobject_class, popup_class->hide_popup = gcrd_hide;
g_object_class_install_property (
gobject_class,
PROP_USE_BUTTONS, PROP_USE_BUTTONS,
g_param_spec_boolean ("use-buttons", g_param_spec_boolean ("use-buttons",
NULL, NULL,
NULL, NULL,
TRUE, TRUE,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
} }
static void static void
gcrd_set_property (GObject *object, gcrd_set_property (GObject *object,
guint param_id, guint param_id,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
GncCellRendererDate *date; GncCellRendererDate *date = GNC_CELL_RENDERER_DATE(object);
date = GNC_CELL_RENDERER_DATE (object); switch (param_id)
{
switch (param_id) { case PROP_USE_BUTTONS:
case PROP_USE_BUTTONS: date->use_buttons = g_value_get_boolean (value);
date->use_buttons = g_value_get_boolean (value);
if (date->use_buttons) if (date->use_buttons)
gtk_widget_show (date->button_box); gtk_widget_show (date->button_box);
else else
gtk_widget_hide (date->button_box); gtk_widget_hide (date->button_box);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break; break;
} }
} }
static void static void
gcrd_get_property (GObject *object, gcrd_get_property (GObject *object,
guint param_id, guint param_id,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
GncCellRendererDate *date; GncCellRendererDate *date = GNC_CELL_RENDERER_DATE (object);
date = GNC_CELL_RENDERER_DATE (object); switch (param_id)
{
switch (param_id) { case PROP_USE_BUTTONS:
case PROP_USE_BUTTONS: g_value_set_boolean (value, date->use_buttons);
g_value_set_boolean (value, date->use_buttons); break;
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break; break;
} }
} }
GtkCellEditable * GtkCellEditable *
gcrd_start_editing (GtkCellRenderer *cell, gcrd_start_editing (GtkCellRenderer *cell,
GdkEvent *event, GdkEvent *event,
GtkWidget *widget, GtkWidget *widget,
const gchar *path, const gchar *path,
const GdkRectangle *background_area, const GdkRectangle *background_area,
const GdkRectangle *cell_area, const GdkRectangle *cell_area,
GtkCellRendererState flags) GtkCellRendererState flags)
{ {
GNC_CELL_RENDERER_POPUP (cell)->editing_canceled = FALSE; GNC_CELL_RENDERER_POPUP(cell)->editing_canceled = FALSE;
if (GTK_CELL_RENDERER_CLASS (parent_class)->start_editing) {
return GTK_CELL_RENDERER_CLASS (parent_class)->start_editing (
cell,
event,
widget,
path,
background_area,
cell_area,
flags);
}
return NULL; if (GTK_CELL_RENDERER_CLASS(parent_class)->start_editing) {
return GTK_CELL_RENDERER_CLASS(parent_class)->start_editing (
cell,
event,
widget,
path,
background_area,
cell_area,
flags);
}
return NULL;
} }
static void static void
gcrd_hide (GncCellRendererPopup *cell) gcrd_hide (GncCellRendererPopup *cell)
{ {
if (parent_class->hide_popup) { if (parent_class->hide_popup) {
parent_class->hide_popup (cell); parent_class->hide_popup (cell);
} }
} }
static void static void
gcrd_show (GncCellRendererPopup *cell, gcrd_show (GncCellRendererPopup *cell,
const gchar *path, const gchar *path,
gint x1, gint x1,
gint y1, gint y1,
gint x2, gint x2,
gint y2) gint y2)
{ {
GncCellRendererDate *date; GncCellRendererDate *date = GNC_CELL_RENDERER_DATE (cell);
gint year = 0; gint year = 0;
gint month = 0; gint month = 0;
gint day = 0; gint day = 0;
const gchar *text; const gchar *text;
if (parent_class->show_popup) { if (parent_class->show_popup) {
parent_class->show_popup (cell, parent_class->show_popup (cell,
path, path,
x1, y1, x1, y1,
x2, y2); x2, y2);
} }
date = GNC_CELL_RENDERER_DATE (cell); text = gnc_popup_entry_get_text (GNC_POPUP_ENTRY (GNC_CELL_RENDERER_POPUP (cell)->editable));
text = gnc_popup_entry_get_text (GNC_POPUP_ENTRY (GNC_CELL_RENDERER_POPUP (cell)->editable)); if (!(g_strcmp0(text, "")))
{
date->time = gnc_time (NULL);
gcrd_time2dmy (date->time, &day, &month, &year);
}
else
{
date->time = gcrd_string_dmy2time (text);
gcrd_time2dmy (date->time, &day, &month, &year);
}
if (!(g_strcmp0(text, ""))) gtk_calendar_clear_marks (GTK_CALENDAR(date->calendar));
{ gtk_calendar_select_month (GTK_CALENDAR(date->calendar), month - 1, year);
date->time = gnc_time (NULL);
gcrd_time2dmy ( date->time, &day, &month, &year);
}
else
{
date->time = gcrd_string_dmy2time (text);
gcrd_time2dmy ( date->time, &day, &month, &year);
}
gtk_calendar_clear_marks (GTK_CALENDAR (date->calendar)); gtk_calendar_select_day (GTK_CALENDAR(date->calendar), day);
gtk_calendar_select_month (GTK_CALENDAR (date->calendar), month - 1, year); gtk_calendar_mark_day (GTK_CALENDAR(date->calendar), day);
gtk_calendar_select_day (GTK_CALENDAR (date->calendar), day);
gtk_calendar_mark_day (GTK_CALENDAR (date->calendar), day);
} }
GtkCellRenderer * GtkCellRenderer *
gnc_cell_renderer_date_new (gboolean use_buttons) gnc_cell_renderer_date_new (gboolean use_buttons)
{ {
GObject *cell; GObject *cell;
cell = g_object_new (GNC_TYPE_CELL_RENDERER_DATE, cell = g_object_new (GNC_TYPE_CELL_RENDERER_DATE,
"use-buttons", use_buttons, "use-buttons", use_buttons,
NULL); NULL);
return GTK_CELL_RENDERER (cell); return GTK_CELL_RENDERER(cell);
} }
static void static void
gcrd_today_clicked (GtkWidget *button, GncCellRendererDate *cell) gcrd_today_clicked (GtkWidget *button, GncCellRendererDate *cell)
{ {
time64 today; time64 today;
gint year = 0, month = 0, day = 0; gint year = 0, month = 0, day = 0;
today = gnc_time (NULL);
gcrd_time2dmy ( today, &day, &month, &year); today = gnc_time (NULL);
gtk_calendar_clear_marks (GTK_CALENDAR (cell->calendar)); gcrd_time2dmy (today, &day, &month, &year);
gtk_calendar_select_month (GTK_CALENDAR (cell->calendar), month - 1, year);
gtk_calendar_select_day (GTK_CALENDAR (cell->calendar), day); gtk_calendar_clear_marks (GTK_CALENDAR(cell->calendar));
gtk_calendar_mark_day (GTK_CALENDAR (cell->calendar), day); gtk_calendar_select_month (GTK_CALENDAR(cell->calendar), month - 1, year);
gtk_calendar_select_day (GTK_CALENDAR(cell->calendar), day);
gtk_calendar_mark_day (GTK_CALENDAR(cell->calendar), day);
} }
static void static void
gcrd_selected_double_click (GtkWidget *calendar, GncCellRendererDate *cell) gcrd_selected_double_click (GtkWidget *calendar, GncCellRendererDate *cell)
{ {
GncCellRendererPopup *popup; GncCellRendererPopup *popup = GNC_CELL_RENDERER_POPUP(cell);
popup = GNC_CELL_RENDERER_POPUP (cell);
gcrd_ok_clicked (popup->popup_window, cell); gcrd_ok_clicked (popup->popup_window, cell);
} }
static void static void
gcrd_cancel_clicked (GtkWidget *popup_window, GncCellRendererDate *cell) gcrd_cancel_clicked (GtkWidget *popup_window, GncCellRendererDate *cell)
{ {
GncCellRendererPopup *popup; GncCellRendererPopup *popup = GNC_CELL_RENDERER_POPUP(cell);
popup = GNC_CELL_RENDERER_POPUP (cell);
popup->editing_canceled = TRUE; popup->editing_canceled = TRUE;
gnc_cell_renderer_popup_hide (popup); gnc_cell_renderer_popup_hide (popup);
} }
static void static void
gcrd_ok_clicked (GtkWidget *popup_window, GncCellRendererDate *cell) gcrd_ok_clicked (GtkWidget *popup_window, GncCellRendererDate *cell)
{ {
GncCellRendererPopup *popup; GncCellRendererPopup *popup = GNC_CELL_RENDERER_POPUP(cell);
popup = GNC_CELL_RENDERER_POPUP (cell);
gcrd_day_selected (popup_window, cell); gcrd_day_selected (popup_window, cell);
popup->editing_canceled = FALSE; popup->editing_canceled = FALSE;
gnc_cell_renderer_popup_hide (popup); gnc_cell_renderer_popup_hide (popup);
} }
static void static void
gcrd_day_selected (GtkWidget *popup_window, GncCellRendererDate *cell) gcrd_day_selected (GtkWidget *popup_window, GncCellRendererDate *cell)
{ {
guint year; guint year;
guint month; guint month;
guint day; guint day;
time64 t; time64 t;
gchar *str; gchar *str;
gtk_calendar_get_date (GTK_CALENDAR (cell->calendar), gtk_calendar_get_date (GTK_CALENDAR(cell->calendar),
&year, &year,
&month, &month,
&day); &day);
t = gcrd_dmy2time ( day, month + 1, year); t = gcrd_dmy2time (day, month + 1, year);
cell->time = t; cell->time = t;
str = gcrd_time2dmy_string (t); str = gcrd_time2dmy_string (t);
gnc_popup_entry_set_text ( gnc_popup_entry_set_text (
GNC_POPUP_ENTRY (GNC_CELL_RENDERER_POPUP (cell)->editable), str); GNC_POPUP_ENTRY(GNC_CELL_RENDERER_POPUP(cell)->editable), str);
g_free (str); g_free (str);
} }
@ -435,7 +425,7 @@ gboolean
gcrd_time2dmy (time64 raw_time, gint *day, gint *month, gint *year) gcrd_time2dmy (time64 raw_time, gint *day, gint *month, gint *year)
{ {
struct tm * timeinfo; struct tm * timeinfo;
timeinfo = gnc_localtime (&raw_time); timeinfo = gnc_localtime (&raw_time);
if (timeinfo == NULL) if (timeinfo == NULL)
return FALSE; return FALSE;
@ -460,7 +450,6 @@ gcrd_dmy2time (gint day, gint month, gint year)
return gnc_mktime (&when); return gnc_mktime (&when);
} }
/* This function converts a time64 value date to a string */ /* This function converts a time64 value date to a string */
static gchar * static gchar *
gcrd_time2dmy_string (time64 raw_time) gcrd_time2dmy_string (time64 raw_time)
@ -468,7 +457,6 @@ gcrd_time2dmy_string (time64 raw_time)
return qof_print_date (raw_time); return qof_print_date (raw_time);
} }
/* This function converts a string date to a time64 value */ /* This function converts a string date to a time64 value */
static time64 static time64
gcrd_string_dmy2time (const gchar *date_string) gcrd_string_dmy2time (const gchar *date_string)
@ -477,8 +465,8 @@ gcrd_string_dmy2time (const gchar *date_string)
if(qof_scan_date (date_string, &day, &month, &year)) if(qof_scan_date (date_string, &day, &month, &year))
{ {
struct tm when; struct tm when;
memset (&when, 0, sizeof (when)); memset (&when, 0, sizeof (when));
when.tm_year = year - 1900; when.tm_year = year - 1900;
when.tm_mon = month - 1 ; when.tm_mon = month - 1 ;
when.tm_mday = day; when.tm_mday = day;
@ -487,7 +475,7 @@ gcrd_string_dmy2time (const gchar *date_string)
} }
else else
{ {
return gnc_time (NULL); return gnc_time (NULL);
} }
} }

View File

@ -41,7 +41,17 @@ static void gnc_popup_entry_init (GncPopupEntry *entry);
static void gnc_popup_entry_class_init (GncPopupEntryClass *klass); static void gnc_popup_entry_class_init (GncPopupEntryClass *klass);
static void gpw_cell_editable_init (GtkCellEditableIface *iface); static void gpw_cell_editable_init (GtkCellEditableIface *iface);
static gboolean gpw_key_press_event (GtkWidget *box, static gboolean gpw_key_press_event (GtkWidget *box,
GdkEventKey *key_event); GdkEventKey *key_event);
static void gpw_set_property (GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec);
static void gpw_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec);
enum enum
{ {
@ -49,6 +59,12 @@ enum
LAST_SIGNAL LAST_SIGNAL
}; };
enum
{
PROP_0,
PROP_EDITING_CANCELED,
};
static GtkEventBoxClass *parent_class; static GtkEventBoxClass *parent_class;
static guint signals[LAST_SIGNAL]; static guint signals[LAST_SIGNAL];
@ -62,11 +78,11 @@ gnc_popup_entry_get_type (void)
static const GTypeInfo widget_info = static const GTypeInfo widget_info =
{ {
sizeof (GncPopupEntryClass), sizeof (GncPopupEntryClass),
NULL, /* base_init */ NULL, /* base_init */
NULL, /* base_finalize */ NULL, /* base_finalize */
(GClassInitFunc) gnc_popup_entry_class_init, (GClassInitFunc) gnc_popup_entry_class_init,
NULL, /* class_finalize */ NULL, /* class_finalize */
NULL, /* class_data */ NULL, /* class_data */
sizeof (GncPopupEntry), sizeof (GncPopupEntry),
0, /* n_preallocs */ 0, /* n_preallocs */
(GInstanceInitFunc) gnc_popup_entry_init, (GInstanceInitFunc) gnc_popup_entry_init,
@ -97,12 +113,14 @@ gnc_popup_entry_init (GncPopupEntry *widget)
{ {
GtkWidget *arrow; GtkWidget *arrow;
widget->editing_canceled = FALSE;
widget->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); widget->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous (GTK_BOX (widget->hbox), FALSE); gtk_box_set_homogeneous (GTK_BOX(widget->hbox), FALSE);
gtk_widget_show (widget->hbox); gtk_widget_show (widget->hbox);
widget->entry = g_object_new (GTK_TYPE_ENTRY, "has_frame", FALSE, NULL); widget->entry = g_object_new (GTK_TYPE_ENTRY, "has_frame", FALSE, NULL);
gtk_entry_set_visibility (GTK_ENTRY (widget->entry), TRUE); gtk_entry_set_visibility (GTK_ENTRY(widget->entry), TRUE);
gtk_widget_show (widget->entry); gtk_widget_show (widget->entry);
widget->button = gtk_button_new (); widget->button = gtk_button_new ();
@ -111,30 +129,38 @@ gnc_popup_entry_init (GncPopupEntry *widget)
arrow = gtk_image_new_from_icon_name ("go-down", GTK_ICON_SIZE_BUTTON); arrow = gtk_image_new_from_icon_name ("go-down", GTK_ICON_SIZE_BUTTON);
gtk_widget_show (arrow); gtk_widget_show (arrow);
g_signal_connect (G_OBJECT (arrow), "draw", g_signal_connect (G_OBJECT(arrow), "draw",
G_CALLBACK (gnc_draw_arrow_cb), GINT_TO_POINTER(1)); G_CALLBACK(gnc_draw_arrow_cb), GINT_TO_POINTER(1));
gtk_container_add (GTK_CONTAINER (widget->button), arrow); gtk_container_add (GTK_CONTAINER(widget->button), arrow);
gtk_box_pack_start (GTK_BOX (widget->hbox), widget->entry, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX(widget->hbox), widget->entry, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (widget->hbox), widget->button, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX(widget->hbox), widget->button, FALSE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (widget), widget->hbox); gtk_container_add (GTK_CONTAINER(widget), widget->hbox);
gtk_widget_set_can_focus (GTK_WIDGET (widget), TRUE); gtk_widget_set_can_focus (GTK_WIDGET(widget), TRUE);
gtk_widget_add_events (GTK_WIDGET (widget), GDK_KEY_PRESS_MASK); gtk_widget_add_events (GTK_WIDGET(widget), GDK_KEY_PRESS_MASK);
gtk_widget_add_events (GTK_WIDGET (widget), GDK_KEY_RELEASE_MASK); gtk_widget_add_events (GTK_WIDGET(widget), GDK_KEY_RELEASE_MASK);
} }
static void static void
gnc_popup_entry_class_init (GncPopupEntryClass *klass) gnc_popup_entry_class_init (GncPopupEntryClass *klass)
{ {
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
widget_class->key_press_event = gpw_key_press_event; widget_class->key_press_event = gpw_key_press_event;
gobject_class->set_property = gpw_set_property;
gobject_class->get_property = gpw_get_property;
parent_class = GTK_EVENT_BOX_CLASS (g_type_class_peek_parent (klass)); parent_class = GTK_EVENT_BOX_CLASS (g_type_class_peek_parent (klass));
g_object_class_override_property (gobject_class,
PROP_EDITING_CANCELED,
"editing-canceled");
signals[ARROW_CLICKED] = g_signal_new signals[ARROW_CLICKED] = g_signal_new
("arrow-clicked", ("arrow-clicked",
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
@ -146,6 +172,42 @@ gnc_popup_entry_class_init (GncPopupEntryClass *klass)
} }
static void
gpw_set_property (GObject *object, guint param_id,
const GValue *value, GParamSpec *pspec)
{
GncPopupEntry *pe = GNC_POPUP_ENTRY(object);
switch (param_id)
{
case PROP_EDITING_CANCELED:
pe->editing_canceled = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
}
}
static void
gpw_get_property (GObject *object, guint param_id,
GValue *value, GParamSpec *pspec)
{
GncPopupEntry *pe = GNC_POPUP_ENTRY(object);
switch (param_id)
{
case PROP_EDITING_CANCELED:
g_value_set_boolean (value, pe->editing_canceled);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
}
}
static void static void
gpw_arrow_clicked (GtkWidget *button, GncPopupEntry *widget) gpw_arrow_clicked (GtkWidget *button, GncPopupEntry *widget)
{ {
@ -157,8 +219,8 @@ gpw_arrow_clicked (GtkWidget *button, GncPopupEntry *widget)
static void static void
gtk_cell_editable_entry_activated (GtkEntry *entry, GncPopupEntry *widget) gtk_cell_editable_entry_activated (GtkEntry *entry, GncPopupEntry *widget)
{ {
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget)); gtk_cell_editable_editing_done (GTK_CELL_EDITABLE(widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget)); gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE(widget));
} }
static gboolean static gboolean
@ -174,8 +236,8 @@ gtk_cell_editable_key_press_event (GtkEntry *entry,
{ {
widget->editing_canceled = TRUE; widget->editing_canceled = TRUE;
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget)); gtk_cell_editable_editing_done (GTK_CELL_EDITABLE(widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget)); gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE(widget));
return TRUE; return TRUE;
} }
@ -194,7 +256,7 @@ gtk_cell_editable_key_press_event (GtkEntry *entry,
return FALSE; return FALSE;
gtk_entry_set_text (entry, qof_print_date (gnc_mktime (&when))); gtk_entry_set_text (entry, qof_print_date (gnc_mktime (&when)));
gtk_widget_grab_focus (GTK_WIDGET (entry)); gtk_widget_grab_focus (GTK_WIDGET(entry));
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@ -204,7 +266,7 @@ static gboolean
gpw_key_press_event (GtkWidget *box, gpw_key_press_event (GtkWidget *box,
GdkEventKey *key_event) GdkEventKey *key_event)
{ {
GncPopupEntry *widget = GNC_POPUP_ENTRY (box); GncPopupEntry *widget = GNC_POPUP_ENTRY(box);
GdkEvent tmp_event; GdkEvent tmp_event;
gtk_widget_grab_focus (widget->entry); gtk_widget_grab_focus (widget->entry);
@ -213,21 +275,21 @@ gpw_key_press_event (GtkWidget *box,
{ {
widget->editing_canceled = TRUE; widget->editing_canceled = TRUE;
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget)); gtk_cell_editable_editing_done (GTK_CELL_EDITABLE(widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget)); gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE(widget));
return TRUE; return TRUE;
} }
if (key_event->keyval == GDK_KEY_Left) if (key_event->keyval == GDK_KEY_Left)
{ {
gtk_editable_set_position (GTK_EDITABLE (widget->entry), 0); gtk_editable_set_position (GTK_EDITABLE(widget->entry), 0);
return TRUE; return TRUE;
} }
if (key_event->keyval == GDK_KEY_Right) if (key_event->keyval == GDK_KEY_Right)
{ {
gtk_editable_set_position (GTK_EDITABLE (widget->entry), -1); gtk_editable_set_position (GTK_EDITABLE(widget->entry), -1);
return TRUE; return TRUE;
} }
@ -239,29 +301,29 @@ gpw_key_press_event (GtkWidget *box,
gtk_widget_event (widget->entry, &tmp_event); gtk_widget_event (widget->entry, &tmp_event);
return GTK_WIDGET_CLASS (parent_class)->key_press_event (GTK_WIDGET (widget), return GTK_WIDGET_CLASS (parent_class)->key_press_event (GTK_WIDGET(widget),
key_event); key_event);
} }
static void static void
gpw_start_editing (GtkCellEditable *cell_editable, gpw_start_editing (GtkCellEditable *cell_editable,
GdkEvent *event) GdkEvent *event)
{ {
GncPopupEntry *widget = GNC_POPUP_ENTRY (cell_editable); GncPopupEntry *widget = GNC_POPUP_ENTRY(cell_editable);
gtk_editable_select_region (GTK_EDITABLE (widget->entry), 0, -1); gtk_editable_select_region (GTK_EDITABLE(widget->entry), 0, -1);
g_signal_connect (G_OBJECT (widget->entry), g_signal_connect (G_OBJECT(widget->entry),
"activate", "activate",
G_CALLBACK (gtk_cell_editable_entry_activated), G_CALLBACK(gtk_cell_editable_entry_activated),
widget); widget);
g_signal_connect (G_OBJECT (widget->entry), g_signal_connect (G_OBJECT(widget->entry),
"key_press_event", "key_press_event",
G_CALLBACK (gtk_cell_editable_key_press_event), G_CALLBACK(gtk_cell_editable_key_press_event),
widget); widget);
g_signal_connect (G_OBJECT (widget->button), g_signal_connect (G_OBJECT(widget->button),
"clicked", "clicked",
(GCallback) gpw_arrow_clicked, (GCallback)gpw_arrow_clicked,
widget); widget);
} }
@ -274,17 +336,17 @@ gpw_cell_editable_init (GtkCellEditableIface *iface)
void void
gnc_popup_entry_set_text (GncPopupEntry *popup, const gchar *text) gnc_popup_entry_set_text (GncPopupEntry *popup, const gchar *text)
{ {
g_return_if_fail (GNC_IS_POPUP_ENTRY (popup)); g_return_if_fail (GNC_IS_POPUP_ENTRY(popup));
gtk_entry_set_text (GTK_ENTRY (popup->entry), text ? text : ""); gtk_entry_set_text (GTK_ENTRY(popup->entry), text ? text : "");
} }
const gchar * const gchar *
gnc_popup_entry_get_text (GncPopupEntry *popup) gnc_popup_entry_get_text (GncPopupEntry *popup)
{ {
g_return_val_if_fail (GNC_IS_POPUP_ENTRY (popup), NULL); g_return_val_if_fail (GNC_IS_POPUP_ENTRY(popup), NULL);
return gtk_entry_get_text (GTK_ENTRY (popup->entry)); return gtk_entry_get_text (GTK_ENTRY(popup->entry));
} }
gint gint
@ -299,14 +361,14 @@ gnc_popup_get_button_width (void)
button = gtk_button_new (); button = gtk_button_new ();
gtk_widget_show (button); gtk_widget_show (button);
gtk_container_add (GTK_CONTAINER (window), button); gtk_container_add (GTK_CONTAINER(window), button);
arrow = gtk_image_new_from_icon_name ("go-down", GTK_ICON_SIZE_BUTTON); arrow = gtk_image_new_from_icon_name ("go-down", GTK_ICON_SIZE_BUTTON);
gtk_widget_show (arrow); gtk_widget_show (arrow);
gtk_container_add (GTK_CONTAINER (button), arrow); gtk_container_add (GTK_CONTAINER(button), arrow);
gtk_window_move (GTK_WINDOW (window), -500, -500); gtk_window_move (GTK_WINDOW(window), -500, -500);
gtk_widget_show (window); gtk_widget_show (window);
gtk_widget_get_preferred_size (window, &req, NULL); gtk_widget_get_preferred_size (window, &req, NULL);

View File

@ -64,7 +64,7 @@ GType gnc_popup_entry_get_type (void) G_GNUC_CONST;
GtkWidget *gnc_popup_entry_new (void); GtkWidget *gnc_popup_entry_new (void);
void gnc_popup_entry_set_text (GncPopupEntry *popup, void gnc_popup_entry_set_text (GncPopupEntry *popup,
const gchar *text); const gchar *text);
const gchar *gnc_popup_entry_get_text (GncPopupEntry *popup); const gchar *gnc_popup_entry_get_text (GncPopupEntry *popup);

View File

@ -36,53 +36,57 @@
#include "gnc-cell-renderer-popup-entry.h" #include "gnc-cell-renderer-popup-entry.h"
enum { enum {
SHOW_POPUP, SHOW_POPUP,
HIDE_POPUP, HIDE_POPUP,
LAST_SIGNAL LAST_SIGNAL
}; };
static void gcrp_init (GncCellRendererPopup *popup); static void gcrp_init (GncCellRendererPopup *popup);
static void gcrp_class_init (GncCellRendererPopupClass *klass); static void gcrp_class_init (GncCellRendererPopupClass *klass);
static GtkCellEditable * static GtkCellEditable *gcrp_start_editing (GtkCellRenderer *cell,
gcrp_start_editing (GtkCellRenderer *cell, GdkEvent *event,
GdkEvent *event, GtkWidget *widget,
GtkWidget *widget, const gchar *path,
const gchar *path, const GdkRectangle *background_area,
const GdkRectangle *background_area, const GdkRectangle *cell_area,
const GdkRectangle *cell_area, GtkCellRendererState flags);
GtkCellRendererState flags);
static void gcrp_show_popup (GncCellRendererPopup *cell,
const gchar *path,
gint x1,
gint y1,
gint x2,
gint y2);
static void gcrp_hide_popup (GncCellRendererPopup *cell);
static void gcrp_get_size (GtkCellRenderer *cell,
GtkWidget *widget,
const GdkRectangle *cell_area,
gint *x_offset,
gint *y_offset,
gint *width,
gint *height);
static void gcrp_style_set (GtkWidget *widget,
GtkStyle *old_style,
GncCellRendererPopup *popup);
static gboolean gcrp_key_press_event (GtkWidget *popup_window,
GdkEventKey *event,
GncCellRendererPopup *cell);
static gboolean gcrp_button_press_event (GtkWidget *widget,
GdkEventButton *event,
GncCellRendererPopup *popup);
static void gcrp_show_popup (GncCellRendererPopup *cell,
const gchar *path,
gint x1,
gint y1,
gint x2,
gint y2);
void gnc_marshal_VOID__STRING_INT_INT_INT_INT (GClosure *closure, static void gcrp_hide_popup (GncCellRendererPopup *cell);
GValue *return_value,
guint n_param_values, static void gcrp_get_size (GtkCellRenderer *cell,
const GValue *param_values, GtkWidget *widget,
gpointer invocation_hint, const GdkRectangle *cell_area,
gpointer marshal_data); gint *x_offset,
gint *y_offset,
gint *width,
gint *height);
static void gcrp_style_set (GtkWidget *widget,
GtkStyle *old_style,
GncCellRendererPopup *popup);
static gboolean gcrp_key_press_event (GtkWidget *popup_window,
GdkEventKey *event,
GncCellRendererPopup *cell);
static gboolean gcrp_button_press_event (GtkWidget *widget,
GdkEventButton *event,
GncCellRendererPopup *popup);
void gnc_marshal_VOID__STRING_INT_INT_INT_INT (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data);
static GtkCellRendererTextClass *parent_class; static GtkCellRendererTextClass *parent_class;
@ -93,127 +97,125 @@ static guint signals[LAST_SIGNAL];
GType GType
gnc_cell_renderer_popup_get_type (void) gnc_cell_renderer_popup_get_type (void)
{ {
static GType cell_text_type = 0; static GType cell_text_type = 0;
if (!cell_text_type) { if (!cell_text_type) {
static const GTypeInfo cell_text_info = { static const GTypeInfo cell_text_info = {
sizeof (GncCellRendererPopupClass), sizeof (GncCellRendererPopupClass),
NULL, /* base_init */ NULL, /* base_init */
NULL, /* base_finalize */ NULL, /* base_finalize */
(GClassInitFunc) gcrp_class_init, (GClassInitFunc) gcrp_class_init,
NULL, /* class_finalize */ NULL, /* class_finalize */
NULL, /* class_data */ NULL, /* class_data */
sizeof (GncCellRendererPopup), sizeof (GncCellRendererPopup),
0, /* n_preallocs */ 0, /* n_preallocs */
(GInstanceInitFunc) gcrp_init, (GInstanceInitFunc) gcrp_init,
}; };
cell_text_type = g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT, cell_text_type = g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT,
"GncCellRendererPopup", "GncCellRendererPopup",
&cell_text_info, &cell_text_info,
0); 0);
} }
return cell_text_type; return cell_text_type;
} }
static void static void
gcrp_init (GncCellRendererPopup *popup) gcrp_init (GncCellRendererPopup *popup)
{ {
popup->popup_window = gtk_window_new (GTK_WINDOW_POPUP); popup->popup_window = gtk_window_new (GTK_WINDOW_POPUP);
popup->button_width = -1; popup->button_width = -1;
g_signal_connect (popup->popup_window,
"button-press-event",
G_CALLBACK (gcrp_button_press_event),
popup);
g_signal_connect (popup->popup_window, g_signal_connect (popup->popup_window,
"key-press-event", "button-press-event",
G_CALLBACK (gcrp_key_press_event), G_CALLBACK(gcrp_button_press_event),
popup); popup);
g_signal_connect (popup->popup_window, g_signal_connect (popup->popup_window,
"style-set", "key-press-event",
G_CALLBACK (gcrp_style_set), G_CALLBACK(gcrp_key_press_event),
popup); popup);
g_signal_connect (popup->popup_window,
"style-set",
G_CALLBACK(gcrp_style_set),
popup);
} }
static void static void
gcrp_class_init (GncCellRendererPopupClass *klass) gcrp_class_init (GncCellRendererPopupClass *klass)
{ {
GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass); GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(klass);
parent_class = GTK_CELL_RENDERER_TEXT_CLASS (g_type_class_peek_parent (klass));
cell_class->start_editing = gcrp_start_editing;
cell_class->get_size = gcrp_get_size;
klass->show_popup = gcrp_show_popup; parent_class = GTK_CELL_RENDERER_TEXT_CLASS(g_type_class_peek_parent (klass));
klass->hide_popup = gcrp_hide_popup;
signals[SHOW_POPUP] = g_signal_new ( cell_class->start_editing = gcrp_start_editing;
"show-popup", cell_class->get_size = gcrp_get_size;
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GncCellRendererPopupClass, show_popup),
NULL, NULL,
gnc_marshal_VOID__STRING_INT_INT_INT_INT,
G_TYPE_NONE, 5,
G_TYPE_STRING,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT);
signals[HIDE_POPUP] = g_signal_new ( klass->show_popup = gcrp_show_popup;
"hide-popup", klass->hide_popup = gcrp_hide_popup;
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, signals[SHOW_POPUP] = g_signal_new (
G_STRUCT_OFFSET (GncCellRendererPopupClass, hide_popup), "show-popup",
NULL, NULL, G_TYPE_FROM_CLASS (klass),
g_cclosure_marshal_VOID__VOID, G_SIGNAL_RUN_LAST,
G_TYPE_NONE, 0); G_STRUCT_OFFSET (GncCellRendererPopupClass, show_popup),
NULL, NULL,
gnc_marshal_VOID__STRING_INT_INT_INT_INT,
G_TYPE_NONE, 5,
G_TYPE_STRING,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT);
signals[HIDE_POPUP] = g_signal_new (
"hide-popup",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GncCellRendererPopupClass, hide_popup),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
} }
static void static void
gcrp_editing_done (GtkCellEditable *editable, gcrp_editing_done (GtkCellEditable *editable,
GncCellRendererPopup *cell) GncCellRendererPopup *cell)
{ {
gchar *path; gchar *path;
const gchar *new_text; const gchar *new_text;
if (GNC_POPUP_ENTRY (editable)->editing_canceled || if (GNC_POPUP_ENTRY(editable)->editing_canceled ||
cell->editing_canceled) { cell->editing_canceled) {
gtk_cell_renderer_stop_editing (GTK_CELL_RENDERER (cell), TRUE); gtk_cell_renderer_stop_editing (GTK_CELL_RENDERER(cell), TRUE);
return; return;
} }
path = g_object_get_data (G_OBJECT (editable),
GNC_CELL_RENDERER_POPUP_PATH);
new_text = gnc_popup_entry_get_text (GNC_POPUP_ENTRY (editable));
gtk_cell_renderer_stop_editing (GTK_CELL_RENDERER (cell), FALSE); path = g_object_get_data (G_OBJECT(editable),
GNC_CELL_RENDERER_POPUP_PATH);
g_signal_emit_by_name (cell, new_text = gnc_popup_entry_get_text (GNC_POPUP_ENTRY(editable));
"edited",
path, gtk_cell_renderer_stop_editing (GTK_CELL_RENDERER(cell), FALSE);
new_text);
g_signal_emit_by_name (cell, "edited", path, new_text);
} }
static void static void
gcrp_style_set (GtkWidget *widget, gcrp_style_set (GtkWidget *widget,
GtkStyle *old_style, GtkStyle *old_style,
GncCellRendererPopup *popup) GncCellRendererPopup *popup)
{ {
/* Invalidate the cache. */ /* Invalidate the cache. */
popup->button_width = -1; popup->button_width = -1;
} }
static gboolean static gboolean
gcrp_grab_on_window (GdkWindow *window, gcrp_grab_on_window (GdkWindow *window,
guint32 activate_time) guint32 activate_time)
{ {
GdkDisplay *display = gdk_display_get_default (); GdkDisplay *display = gdk_display_get_default ();
#if GTK_CHECK_VERSION(3,20,0) #if GTK_CHECK_VERSION(3,20,0)
@ -247,7 +249,7 @@ gcrp_grab_on_window (GdkWindow *window,
if (gdk_device_grab (device, window, GDK_OWNERSHIP_WINDOW, TRUE, if (gdk_device_grab (device, window, GDK_OWNERSHIP_WINDOW, TRUE,
GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
NULL, activate_time) == GDK_GRAB_SUCCESS) NULL, activate_time) == GDK_GRAB_SUCCESS)
#endif #endif
return TRUE; return TRUE;
else { else {
@ -264,315 +266,308 @@ gcrp_grab_on_window (GdkWindow *window,
static void static void
gcrp_show_popup (GncCellRendererPopup *cell, gcrp_show_popup (GncCellRendererPopup *cell,
const gchar *path, const gchar *path,
gint x1, gint x1,
gint y1, gint y1,
gint x2, gint x2,
gint y2) gint y2)
{ {
#if GTK_CHECK_VERSION(3,22,0) #if GTK_CHECK_VERSION(3,22,0)
GdkWindow *win; GdkWindow *win;
GdkMonitor *mon; GdkMonitor *mon;
GdkRectangle monitor_size; GdkRectangle monitor_size;
#endif #endif
GtkAllocation alloc; GtkAllocation alloc;
gint x, y; gint x, y;
gint screen_height, screen_width; gint screen_height, screen_width;
gint button_height; gint button_height;
cell->shown = TRUE; cell->shown = TRUE;
gtk_widget_realize (cell->popup_window); gtk_widget_realize (cell->popup_window);
/* I'm not sure this is ok to do, but we need to show the window to be /* I'm not sure this is ok to do, but we need to show the window to be
* able to get the allocation right. * able to get the allocation right.
*/ */
gtk_window_move (GTK_WINDOW (cell->popup_window), -500, -500); gtk_window_move (GTK_WINDOW (cell->popup_window), -500, -500);
gtk_widget_show (cell->popup_window); gtk_widget_show (cell->popup_window);
gtk_widget_get_allocation (cell->popup_window, &alloc); gtk_widget_get_allocation (cell->popup_window, &alloc);
x = x2; x = x2;
y = y2; y = y2;
button_height = y2 - y1; button_height = y2 - y1;
#if GTK_CHECK_VERSION(3,22,0) #if GTK_CHECK_VERSION(3,22,0)
win = gdk_screen_get_root_window (gtk_window_get_screen (GTK_WINDOW (cell->popup_window))); win = gdk_screen_get_root_window (gtk_window_get_screen (GTK_WINDOW(cell->popup_window)));
mon = gdk_display_get_monitor_at_window (gtk_widget_get_display (GTK_WIDGET(cell->popup_window)), win); mon = gdk_display_get_monitor_at_window (gtk_widget_get_display (GTK_WIDGET(cell->popup_window)), win);
gdk_monitor_get_geometry (mon, &monitor_size); gdk_monitor_get_geometry (mon, &monitor_size);
screen_width = monitor_size.width; screen_width = monitor_size.width;
screen_height = monitor_size.height - y; screen_height = monitor_size.height - y;
#else #else
screen_width = gdk_screen_width(); screen_width = gdk_screen_width();
screen_height = gdk_screen_height() - y; screen_height = gdk_screen_height() - y;
#endif #endif
/* Check if it fits in the available height. */
if (alloc.height > screen_height) {
/* It doesn't fit, so we see if we have the minimum space needed. */
if (alloc.height > screen_height && y - button_height > screen_height) {
/* We don't, so we show the popup above the cell
instead of below it. */
y -= (alloc.height + button_height);
if (y < 0) {
y = 0;
}
}
}
/* We try to line it up with the right edge of the column, but we don't /* Check if it fits in the available height. */
* want it to go off the edges of the screen. if (alloc.height > screen_height)
*/ {
if (x > screen_width) { /* It doesn't fit, so we see if we have the minimum space needed. */
x = screen_width; if (alloc.height > screen_height && y - button_height > screen_height)
} {
/* We don't, so we show the popup above the cell
instead of below it. */
y -= (alloc.height + button_height);
if (y < 0) {
y = 0;
}
}
}
x -= alloc.width; /* We try to line it up with the right edge of the column, but we don't
if (x < 0) { * want it to go off the edges of the screen.
x = 0; */
} if (x > screen_width)
x = screen_width;
gtk_grab_add (cell->popup_window); x -= alloc.width;
gtk_window_move (GTK_WINDOW (cell->popup_window), x, y); if (x < 0)
gtk_widget_show (cell->popup_window); x = 0;
gtk_widget_grab_focus (cell->focus_window); gtk_grab_add (cell->popup_window);
gcrp_grab_on_window (gtk_widget_get_window (cell->popup_window), gtk_window_move (GTK_WINDOW(cell->popup_window), x, y);
gtk_get_current_event_time ()); gtk_widget_show (cell->popup_window);
gtk_widget_grab_focus (cell->focus_window);
gcrp_grab_on_window (gtk_widget_get_window (cell->popup_window),
gtk_get_current_event_time ());
} }
static void static void
gcrp_hide_popup (GncCellRendererPopup *cell) gcrp_hide_popup (GncCellRendererPopup *cell)
{ {
gtk_grab_remove (cell->popup_window); gtk_grab_remove (cell->popup_window);
gtk_widget_hide (cell->popup_window); gtk_widget_hide (cell->popup_window);
if (cell->editable) { if (cell->editable)
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (cell->editable)); gtk_cell_editable_editing_done (GTK_CELL_EDITABLE(cell->editable));
}
/* This may look weird (the test), but the weak pointer will actually be /* This may look weird (the test), but the weak pointer will actually be
* nulled out for some cells, like the date cell. * nulled out for some cells, like the date cell.
*/ */
if (cell->editable) { if (cell->editable)
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (cell->editable)); gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE(cell->editable));
}
cell->shown = FALSE;
cell->shown = FALSE; cell->editing_canceled = FALSE;
cell->editing_canceled = FALSE;
} }
static void static void
gcrp_arrow_clicked (GtkCellEditable *entry, gcrp_arrow_clicked (GtkCellEditable *entry,
GncCellRendererPopup *cell) GncCellRendererPopup *cell)
{ {
GtkAllocation alloc; GtkAllocation alloc;
gint x, y; gint x, y;
const gchar *path; const gchar *path;
if (cell->shown) {
cell->editing_canceled = TRUE;
gnc_cell_renderer_popup_hide (cell);
return;
}
path = g_object_get_data (G_OBJECT (entry), if (cell->shown)
GNC_CELL_RENDERER_POPUP_PATH); {
cell->editing_canceled = TRUE;
gnc_cell_renderer_popup_hide (cell);
return;
}
/* Temporarily grab pointer and keyboard on a window we know exists; we path = g_object_get_data (G_OBJECT(entry),
* do this so that the grab (with owner events == TRUE) affects GNC_CELL_RENDERER_POPUP_PATH);
* events generated when the window is mapped, such as enter
* notify events on subwidgets. If the grab fails, bail out.
*/
if (!gcrp_grab_on_window (gtk_widget_get_window (GTK_WIDGET (entry)),
gtk_get_current_event_time ())) {
return;
}
gtk_editable_select_region (GTK_EDITABLE (GNC_POPUP_ENTRY (entry)->entry), 0, 0);
gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (entry)), &x, &y); /* Temporarily grab pointer and keyboard on a window we know exists; we
* do this so that the grab (with owner events == TRUE) affects
gtk_widget_get_allocation (GTK_WIDGET (entry), &alloc); * events generated when the window is mapped, such as enter
* notify events on subwidgets. If the grab fails, bail out.
*/
if (!gcrp_grab_on_window (gtk_widget_get_window (GTK_WIDGET(entry)),
gtk_get_current_event_time ())) {
return;
}
g_signal_emit (cell, signals[SHOW_POPUP], 0, gtk_editable_select_region (GTK_EDITABLE(GNC_POPUP_ENTRY(entry)->entry), 0, 0);
path,
x, gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET(entry)), &x, &y);
y,
x + alloc.width, gtk_widget_get_allocation (GTK_WIDGET(entry), &alloc);
y + alloc.height);
g_signal_emit (cell, signals[SHOW_POPUP], 0,
path,
x,
y,
x + alloc.width,
y + alloc.height);
} }
static GtkCellEditable * static GtkCellEditable *
gcrp_start_editing (GtkCellRenderer *cell, gcrp_start_editing (GtkCellRenderer *cell,
GdkEvent *event, GdkEvent *event,
GtkWidget *widget, GtkWidget *widget,
const gchar *path, const gchar *path,
const GdkRectangle *background_area, const GdkRectangle *background_area,
const GdkRectangle *cell_area, const GdkRectangle *cell_area,
GtkCellRendererState flags) GtkCellRendererState flags)
{ {
GncCellRendererPopup *popup; GncCellRendererPopup *popup = GNC_CELL_RENDERER_POPUP(cell);
GtkWidget *editable; GtkWidget *editable;
gchar *text; gchar *text;
gboolean iseditable; gboolean iseditable;
popup = GNC_CELL_RENDERER_POPUP (cell);
g_object_get (G_OBJECT (popup), "editable", &iseditable, NULL); g_object_get (G_OBJECT (popup), "editable", &iseditable, NULL);
/* If the cell isn't editable we return NULL. */
if (iseditable == FALSE) {
return NULL;
}
editable = g_object_new (GNC_TYPE_POPUP_ENTRY, NULL);
g_object_get (G_OBJECT (cell), "text", &text, NULL); /* If the cell isn't editable we return NULL. */
popup->cell_text = text; if (iseditable == FALSE)
return NULL;
gnc_popup_entry_set_text (GNC_POPUP_ENTRY (editable), text ? text : ""); editable = g_object_new (GNC_TYPE_POPUP_ENTRY, NULL);
g_object_set_data_full (G_OBJECT (editable),
GNC_CELL_RENDERER_POPUP_PATH,
g_strdup (path),
g_free);
gtk_widget_show (editable);
g_signal_connect (editable, g_object_get (G_OBJECT(cell), "text", &text, NULL);
"editing-done", popup->cell_text = text;
G_CALLBACK (gcrp_editing_done),
popup);
g_signal_connect (editable, gnc_popup_entry_set_text (GNC_POPUP_ENTRY(editable), text ? text : "");
"arrow-clicked",
G_CALLBACK (gcrp_arrow_clicked),
popup);
popup->editable = editable; g_object_set_data_full (G_OBJECT(editable),
GNC_CELL_RENDERER_POPUP_PATH,
g_strdup (path),
g_free);
g_object_add_weak_pointer (G_OBJECT (popup->editable), gtk_widget_show (editable);
(gpointer) &popup->editable);
g_signal_connect (editable,
return GTK_CELL_EDITABLE (editable); "editing-done",
G_CALLBACK(gcrp_editing_done),
popup);
g_signal_connect (editable,
"arrow-clicked",
G_CALLBACK(gcrp_arrow_clicked),
popup);
popup->editable = editable;
g_object_add_weak_pointer (G_OBJECT(popup->editable),
(gpointer) &popup->editable);
return GTK_CELL_EDITABLE(editable);
} }
GtkCellRenderer * GtkCellRenderer *
gnc_cell_renderer_popup_new (void) gnc_cell_renderer_popup_new (void)
{ {
return GTK_CELL_RENDERER ( return GTK_CELL_RENDERER(
g_object_new (gnc_cell_renderer_popup_get_type (), NULL)); g_object_new (gnc_cell_renderer_popup_get_type (), NULL));
} }
void void
gnc_cell_renderer_popup_hide (GncCellRendererPopup *cell) gnc_cell_renderer_popup_hide (GncCellRendererPopup *cell)
{ {
g_return_if_fail (GNC_IS_CELL_RENDERER_POPUP (cell)); g_return_if_fail (GNC_IS_CELL_RENDERER_POPUP(cell));
g_signal_emit (cell, signals[HIDE_POPUP], 0); g_signal_emit (cell, signals[HIDE_POPUP], 0);
} }
static void static void
gcrp_get_size (GtkCellRenderer *cell, gcrp_get_size (GtkCellRenderer *cell,
GtkWidget *widget, GtkWidget *widget,
const GdkRectangle *cell_area, const GdkRectangle *cell_area,
gint *x_offset, gint *x_offset,
gint *y_offset, gint *y_offset,
gint *width, gint *width,
gint *height) gint *height)
{ {
GncCellRendererPopup *popup; GncCellRendererPopup *popup = GNC_CELL_RENDERER_POPUP (cell);
popup = GNC_CELL_RENDERER_POPUP (cell); if (GTK_CELL_RENDERER_CLASS(parent_class)->get_size) {
(* GTK_CELL_RENDERER_CLASS(parent_class)->get_size) (cell,
if (GTK_CELL_RENDERER_CLASS (parent_class)->get_size) { widget,
(* GTK_CELL_RENDERER_CLASS (parent_class)->get_size) (cell, cell_area,
widget, x_offset,
cell_area, y_offset,
x_offset, width,
y_offset, height);
width, }
height);
}
/* We cache this because it takes really long to get the width. */ /* We cache this because it takes really long to get the width. */
if (popup->button_width == -1) { if (popup->button_width == -1)
popup->button_width = gnc_popup_get_button_width (); popup->button_width = gnc_popup_get_button_width ();
}
*width += popup->button_width;
*width += popup->button_width;
} }
static gboolean static gboolean
gcrp_key_press_event (GtkWidget *popup_window, gcrp_key_press_event (GtkWidget *popup_window,
GdkEventKey *event, GdkEventKey *event,
GncCellRendererPopup *cell) GncCellRendererPopup *cell)
{ {
if (event->keyval != GDK_KEY_Escape && if (event->keyval != GDK_KEY_Escape &&
event->keyval != GDK_KEY_Return && event->keyval != GDK_KEY_Return &&
event->keyval != GDK_KEY_KP_Enter && event->keyval != GDK_KEY_KP_Enter &&
event->keyval != GDK_KEY_ISO_Enter && event->keyval != GDK_KEY_ISO_Enter &&
event->keyval != GDK_KEY_3270_Enter) { event->keyval != GDK_KEY_3270_Enter) {
return FALSE; return FALSE;
} }
if (event->keyval == GDK_KEY_Escape) { if (event->keyval == GDK_KEY_Escape) {
cell->editing_canceled = TRUE; cell->editing_canceled = TRUE;
} else { } else {
cell->editing_canceled = FALSE; cell->editing_canceled = FALSE;
} }
gnc_cell_renderer_popup_hide (cell); gnc_cell_renderer_popup_hide (cell);
return TRUE; return TRUE;
} }
static gboolean static gboolean
gcrp_button_press_event (GtkWidget *widget, gcrp_button_press_event (GtkWidget *widget,
GdkEventButton *event, GdkEventButton *event,
GncCellRendererPopup *popup) GncCellRendererPopup *popup)
{ {
GtkAllocation alloc; GtkAllocation alloc;
gdouble x, y; gdouble x, y;
gint xoffset, yoffset; gint xoffset, yoffset;
gint x1, y1; gint x1, y1;
gint x2, y2; gint x2, y2;
if (event->button != 1) { if (event->button != 1)
return FALSE; return FALSE;
}
/* If the event happened outside the popup, cancel editing.
*/
/*gdk_event_get_root_coords ((GdkEvent *) event, &x, &y);*/ /* If the event happened outside the popup, cancel editing.
x = event->x_root; */
y = event->y_root;
gdk_window_get_root_origin (gtk_widget_get_window (widget), /*gdk_event_get_root_coords ((GdkEvent *) event, &x, &y);*/
&xoffset, x = event->x_root;
&yoffset); y = event->y_root;
gtk_widget_get_allocation (widget, &alloc); gdk_window_get_root_origin (gtk_widget_get_window (widget),
xoffset += alloc.x; &xoffset,
yoffset += alloc.y; &yoffset);
gtk_widget_get_allocation (popup->popup_window, &alloc);
x1 = alloc.x + xoffset;
y1 = alloc.y + yoffset;
x2 = x1 + alloc.width;
y2 = y1 + alloc.height;
if (x > x1 && x < x2 && y > y1 && y < y2) { gtk_widget_get_allocation (widget, &alloc);
return FALSE; xoffset += alloc.x;
} yoffset += alloc.y;
popup->editing_canceled = TRUE; gtk_widget_get_allocation (popup->popup_window, &alloc);
gnc_cell_renderer_popup_hide (popup); x1 = alloc.x + xoffset;
y1 = alloc.y + yoffset;
return FALSE; x2 = x1 + alloc.width;
y2 = y1 + alloc.height;
if (x > x1 && x < x2 && y > y1 && y < y2)
return FALSE;
popup->editing_canceled = TRUE;
gnc_cell_renderer_popup_hide (popup);
return FALSE;
} }
@ -581,43 +576,43 @@ gcrp_button_press_event (GtkWidget *widget,
void void
gnc_marshal_VOID__STRING_INT_INT_INT_INT (GClosure *closure, gnc_marshal_VOID__STRING_INT_INT_INT_INT (GClosure *closure,
GValue *return_value G_GNUC_UNUSED, GValue *return_value G_GNUC_UNUSED,
guint n_param_values, guint n_param_values,
const GValue *param_values, const GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED, gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data) gpointer marshal_data)
{ {
typedef void (*GMarshalFunc_VOID__STRING_INT_INT_INT_INT) (gpointer data1, typedef void (*GMarshalFunc_VOID__STRING_INT_INT_INT_INT) (gpointer data1,
gpointer arg_1, gpointer arg_1,
gint arg_2, gint arg_2,
gint arg_3, gint arg_3,
gint arg_4, gint arg_4,
gint arg_5, gint arg_5,
gpointer data2); gpointer data2);
register GMarshalFunc_VOID__STRING_INT_INT_INT_INT callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
g_return_if_fail (n_param_values == 6); register GMarshalFunc_VOID__STRING_INT_INT_INT_INT callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
if (G_CCLOSURE_SWAP_DATA (closure)) g_return_if_fail (n_param_values == 6);
if (G_CCLOSURE_SWAP_DATA (closure))
{ {
data1 = closure->data; data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0); data2 = g_value_peek_pointer (param_values + 0);
} }
else else
{ {
data1 = g_value_peek_pointer (param_values + 0); data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data; data2 = closure->data;
} }
callback = (GMarshalFunc_VOID__STRING_INT_INT_INT_INT) (marshal_data ? marshal_data : cc->callback); callback = (GMarshalFunc_VOID__STRING_INT_INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
callback (data1, callback (data1,
g_marshal_value_peek_string (param_values + 1), g_marshal_value_peek_string (param_values + 1),
g_marshal_value_peek_int (param_values + 2), g_marshal_value_peek_int (param_values + 2),
g_marshal_value_peek_int (param_values + 3), g_marshal_value_peek_int (param_values + 3),
g_marshal_value_peek_int (param_values + 4), g_marshal_value_peek_int (param_values + 4),
g_marshal_value_peek_int (param_values + 5), g_marshal_value_peek_int (param_values + 5),
data2); data2);
} }

View File

@ -45,50 +45,50 @@ typedef struct _GncCellRendererPopupClass GncCellRendererPopupClass;
struct _GncCellRendererPopup struct _GncCellRendererPopup
{ {
GtkCellRendererText parent; GtkCellRendererText parent;
/* Cached width of the popup button. */ /* Cached width of the popup button. */
gint button_width; gint button_width;
/* The popup window. */
GtkWidget *popup_window;
/* The widget that should grab focus on popup. */ /* The popup window. */
GtkWidget *focus_window; GtkWidget *popup_window;
/* The editable entry. */ /* The widget that should grab focus on popup. */
GtkWidget *editable; GtkWidget *focus_window;
gboolean shown; /* The editable entry. */
gboolean editing_canceled; GtkWidget *editable;
gchar *cell_text;
gboolean shown;
gboolean editing_canceled;
gchar *cell_text;
}; };
struct _GncCellRendererPopupClass struct _GncCellRendererPopupClass
{ {
GtkCellRendererTextClass parent_class; GtkCellRendererTextClass parent_class;
void (* show_popup) (GncCellRendererPopup *cell, void (* show_popup) (GncCellRendererPopup *cell,
const gchar *path, const gchar *path,
gint x1, gint x1,
gint y1, gint y1,
gint x2, gint x2,
gint y2); gint y2);
void (* hide_popup) (GncCellRendererPopup *cell); void (* hide_popup) (GncCellRendererPopup *cell);
}; };
GType gnc_cell_renderer_popup_get_type (void) G_GNUC_CONST; GType gnc_cell_renderer_popup_get_type (void) G_GNUC_CONST;
GtkCellRenderer *gnc_cell_renderer_popup_new (void); GtkCellRenderer *gnc_cell_renderer_popup_new (void);
void gnc_cell_renderer_popup_show (GncCellRendererPopup *cell, void gnc_cell_renderer_popup_show (GncCellRendererPopup *cell,
const gchar *path, const gchar *path,
gint x1, gint x1,
gint y1, gint y1,
gint x2, gint x2,
gint y2); gint y2);
void gnc_cell_renderer_popup_hide (GncCellRendererPopup *cell); void gnc_cell_renderer_popup_hide (GncCellRendererPopup *cell);
#endif /* __GNC_CELL_RENDERER_POPUP_H__ */ #endif /* __GNC_CELL_RENDERER_POPUP_H__ */

View File

@ -59,6 +59,8 @@ typedef struct
GtkWidget *sub_label; GtkWidget *sub_label;
gboolean jump_close; gboolean jump_close;
gchar *saved_filter_text;
gint event_handler_id;
}FindAccountDialog; }FindAccountDialog;
@ -194,7 +196,7 @@ fill_model (GtkTreeModel *model, Account *account)
} }
static void static void
get_account_info (FindAccountDialog *facc_dialog) get_account_info (FindAccountDialog *facc_dialog, gboolean use_saved_filter)
{ {
Account *root; Account *root;
GList *accts; GList *accts;
@ -214,7 +216,10 @@ get_account_info (FindAccountDialog *facc_dialog)
accts = gnc_account_get_descendants_sorted (root); accts = gnc_account_get_descendants_sorted (root);
filter_text = g_ascii_strdown (gtk_entry_get_text (GTK_ENTRY(facc_dialog->filter_text_entry)), -1); if (use_saved_filter)
filter_text = g_ascii_strdown (facc_dialog->saved_filter_text, -1);
else
filter_text = g_ascii_strdown (gtk_entry_get_text (GTK_ENTRY(facc_dialog->filter_text_entry)), -1);
/* disconnect the model from the treeview */ /* disconnect the model from the treeview */
model = gtk_tree_view_get_model (GTK_TREE_VIEW(facc_dialog->view)); model = gtk_tree_view_get_model (GTK_TREE_VIEW(facc_dialog->view));
@ -250,12 +255,55 @@ get_account_info (FindAccountDialog *facc_dialog)
static void static void
filter_button_cb (GtkButton *button, FindAccountDialog *facc_dialog) filter_button_cb (GtkButton *button, FindAccountDialog *facc_dialog)
{ {
get_account_info (facc_dialog); get_account_info (facc_dialog, FALSE);
if (facc_dialog->saved_filter_text)
g_free (facc_dialog->saved_filter_text);
// save the filter incase of an account event
facc_dialog->saved_filter_text = g_strdup (gtk_entry_get_text
(GTK_ENTRY(facc_dialog->filter_text_entry)));
// Clear the filter // Clear the filter
gtk_entry_set_text (GTK_ENTRY(facc_dialog->filter_text_entry), ""); gtk_entry_set_text (GTK_ENTRY(facc_dialog->filter_text_entry), "");
} }
static void
gnc_find_account_event_handler (QofInstance *entity,
QofEventId event_type,
FindAccountDialog *facc_dialog,
gpointer evt_data)
{
Account *account = NULL;
g_return_if_fail (facc_dialog); /* Required */
if (!GNC_IS_ACCOUNT(entity))
return;
ENTER("entity %p of type %d, dialog %p, event_data %p",
entity, event_type, facc_dialog, evt_data);
account = GNC_ACCOUNT(entity);
switch (event_type)
{
case QOF_EVENT_ADD:
case QOF_EVENT_REMOVE:
case QOF_EVENT_MODIFY:
DEBUG("account change on %p (%s)", account, xaccAccountGetName (account));
get_account_info (facc_dialog, TRUE);
LEAVE(" ");
break;
default:
LEAVE("unknown event type");
return;
}
LEAVE(" ");
return;
}
static void static void
gnc_find_account_dialog_create (GtkWidget *parent, FindAccountDialog *facc_dialog) gnc_find_account_dialog_create (GtkWidget *parent, FindAccountDialog *facc_dialog)
{ {
@ -280,6 +328,7 @@ gnc_find_account_dialog_create (GtkWidget *parent, FindAccountDialog *facc_dialo
facc_dialog->session = gnc_get_current_session(); facc_dialog->session = gnc_get_current_session();
facc_dialog->parent = parent; facc_dialog->parent = parent;
facc_dialog->saved_filter_text = g_strdup ("");
gtk_window_set_title (GTK_WINDOW(facc_dialog->window), _("Find Account")); gtk_window_set_title (GTK_WINDOW(facc_dialog->window), _("Find Account"));
@ -400,7 +449,11 @@ gnc_find_account_dialog_create (GtkWidget *parent, FindAccountDialog *facc_dialo
// Set the filter to Wildcard // Set the filter to Wildcard
gtk_entry_set_text (GTK_ENTRY(facc_dialog->filter_text_entry), ""); gtk_entry_set_text (GTK_ENTRY(facc_dialog->filter_text_entry), "");
get_account_info (facc_dialog); // add a handler to listen for account events
facc_dialog->event_handler_id = qof_event_register_handler
((QofEventHandler)gnc_find_account_event_handler, facc_dialog);
get_account_info (facc_dialog, FALSE);
LEAVE(" "); LEAVE(" ");
} }
@ -410,6 +463,16 @@ close_handler (gpointer user_data)
FindAccountDialog *facc_dialog = user_data; FindAccountDialog *facc_dialog = user_data;
ENTER(" "); ENTER(" ");
if (facc_dialog->event_handler_id)
{
qof_event_unregister_handler (facc_dialog->event_handler_id);
facc_dialog->event_handler_id = 0;
}
if (facc_dialog->saved_filter_text)
g_free (facc_dialog->saved_filter_text);
gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(facc_dialog->window)); gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(facc_dialog->window));
gtk_widget_destroy (GTK_WIDGET(facc_dialog->window)); gtk_widget_destroy (GTK_WIDGET(facc_dialog->window));
LEAVE(" "); LEAVE(" ");

View File

@ -107,7 +107,8 @@
(define (gnc:html-document-tree-collapse . tree) (define (gnc:html-document-tree-collapse . tree)
(let lp ((e tree) (accum '())) (let lp ((e tree) (accum '()))
(cond ((list? e) (fold lp accum e)) (cond ((null? e) accum)
((pair? e) (fold lp accum e))
((string? e) (cons e accum)) ((string? e) (cons e accum))
(else (cons (object->string e) accum))))) (else (cons (object->string e) accum)))))
@ -142,6 +143,7 @@
;;<guile-sitedir>/gnucash/reports/data/balsheet-eg.eguile.scm:<html> ;;<guile-sitedir>/gnucash/reports/data/balsheet-eg.eguile.scm:<html>
;;<guile-sitedir>/gnucash/reports/data/receipt.eguile.scm:<html> ;;<guile-sitedir>/gnucash/reports/data/receipt.eguile.scm:<html>
(push "<!DOCTYPE html>\n")
(push "<html dir='auto'>\n") (push "<html dir='auto'>\n")
(push "<head>\n") (push "<head>\n")
(push "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n") (push "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n")

View File

@ -60,104 +60,96 @@
;; Registers font options ;; Registers font options
(define (register-font-options options) (define (register-font-options options)
(let* (define (opt-register opt)
( (gnc:register-option options opt))
(opt-register (let ((font-family (gnc-get-default-report-font-family)))
(lambda (opt) (gnc:register-option options opt))) (opt-register
(font-family (gnc-get-default-report-font-family)) (gnc:make-font-option
) (N_ "Fonts")
(opt-register (N_ "Title") "a" (N_ "Font info for the report title.")
(gnc:make-font-option (string-append font-family " Bold 15")))
(N_ "Fonts") (opt-register
(N_ "Title") "a" (N_ "Font info for the report title.") (gnc:make-font-option
(string-append font-family " Bold 15"))) (N_ "Fonts")
(opt-register (N_ "Account link") "b" (N_ "Font info for account name.")
(gnc:make-font-option (string-append font-family " Italic 10")))
(N_ "Fonts") (opt-register
(N_ "Account link") "b" (N_ "Font info for account name.") (gnc:make-font-option
(string-append font-family " Italic 10"))) (N_ "Fonts")
(opt-register (N_ "Number cell") "c" (N_ "Font info for regular number cells.")
(gnc:make-font-option (string-append font-family " 10")))
(N_ "Fonts") (opt-register
(N_ "Number cell") "c" (N_ "Font info for regular number cells.") (gnc:make-simple-boolean-option
(string-append font-family " 10"))) (N_ "Fonts")
(opt-register (N_ "Negative Values in Red") "d" (N_ "Display negative values in red.")
(gnc:make-simple-boolean-option #t))
(N_ "Fonts") (opt-register
(N_ "Negative Values in Red") "d" (N_ "Display negative values in red.") (gnc:make-font-option
#t)) (N_ "Fonts")
(opt-register (N_ "Number header") "e" (N_ "Font info for number headers.")
(gnc:make-font-option (string-append font-family " 10")))
(N_ "Fonts") (opt-register
(N_ "Number header") "e" (N_ "Font info for number headers.") (gnc:make-font-option
(string-append font-family " 10"))) (N_ "Fonts")
(opt-register (N_ "Text cell") "f" (N_ "Font info for regular text cells.")
(gnc:make-font-option (string-append font-family " 10")))
(N_ "Fonts") (opt-register
(N_ "Text cell") "f" (N_ "Font info for regular text cells.") (gnc:make-font-option
(string-append font-family " 10"))) (N_ "Fonts")
(opt-register (N_ "Total number cell") "g"
(gnc:make-font-option (N_ "Font info for number cells containing a total.")
(N_ "Fonts") (string-append font-family " Bold 12")))
(N_ "Total number cell") "g" (N_ "Font info for number cells containing a total.") (opt-register
(string-append font-family " Bold 12"))) (gnc:make-font-option
(opt-register (N_ "Fonts")
(gnc:make-font-option (N_ "Total label cell") "h"
(N_ "Fonts") (N_ "Font info for cells containing total labels.")
(N_ "Total label cell") "h" (N_ "Font info for cells containing total labels.") (string-append font-family " Bold 12")))
(string-append font-family " Bold 12"))) (opt-register
(opt-register (gnc:make-font-option
(gnc:make-font-option (N_ "Fonts")
(N_ "Fonts") (N_ "Centered label cell") "i" (N_ "Font info for centered label cells.")
(N_ "Centered label cell") "i" (N_ "Font info for centered label cells.") (string-append font-family " Bold 12")))))
(string-append font-family " Bold 12")))
)
)
;; Adds CSS style information to an html document ;; Adds CSS style information to an html document
(define (add-css-information-to-doc options ssdoc doc) (define (add-css-information-to-doc options ssdoc doc)
(let* (define (opt-font-val name)
((opt-val (gnc:option-value (gnc:lookup-option options "Fonts" name)))
(lambda (section name) (define (opt-style-info name) (font-name-to-style-info (opt-font-val name)))
(gnc:option-value (gnc:lookup-option options section name)))) (let* ((negative-red? (opt-font-val "Negative Values in Red"))
(negative-red? (opt-val "Fonts" "Negative Values in Red")) (alternate-row-color
(alternate-row-color (gnc:color-option->html
(gnc:color-option->html (gnc:lookup-option options "Colors" "Alternate Table Cell Color")))
(gnc:lookup-option options (title-info (opt-style-info "Title"))
"Colors" (account-link-info (opt-style-info "Account link"))
"Alternate Table Cell Color"))) (number-cell-info (opt-style-info "Number cell"))
(title-font-info (font-name-to-style-info (opt-val "Fonts" "Title"))) (number-header-info (opt-style-info "Number header"))
(account-link-font-info (font-name-to-style-info (opt-val "Fonts" "Account link"))) (text-cell-info (opt-style-info "Text cell"))
(number-cell-font-info (font-name-to-style-info (opt-val "Fonts" "Number cell"))) (total-number-cell-info (opt-style-info "Total number cell"))
(number-header-font-info (font-name-to-style-info (opt-val "Fonts" "Number header"))) (total-label-cell-info (opt-style-info "Total label cell"))
(text-cell-font-info (font-name-to-style-info (opt-val "Fonts" "Text cell"))) (centered-label-cell-info (opt-style-info "Centered label cell")))
(total-number-cell-font-info (font-name-to-style-info (opt-val "Fonts" "Total number cell")))
(total-label-cell-font-info (font-name-to-style-info (opt-val "Fonts" "Total label cell")))
(centered-label-cell-font-info (font-name-to-style-info (opt-val "Fonts" "Centered label cell"))))
(gnc:html-document-set-style-text! (gnc:html-document-set-style-text!
ssdoc ssdoc
(string-append (string-append
"h3 { " title-font-info " }\n" "h3 { " title-info " }\n"
"a { " account-link-font-info " }\n" "a { " account-link-info " }\n"
"body, p, table, tr, td { vertical-align: top; " text-cell-font-info " }\n" "body, p, table, tr, td { vertical-align: top; " text-cell-info " }\n"
"tr.alternate-row { background: " alternate-row-color " }\n" "tr.alternate-row { background: " alternate-row-color " }\n"
"tr { page-break-inside: avoid !important;}\n" "tr { page-break-inside: avoid !important;}\n"
"th.column-heading-left { text-align: left; " number-header-font-info " }\n" "html, body { height: 100vh; margin: 0; }\n"
"th.column-heading-center { text-align: center; " number-header-font-info " }\n" "td, th { border-color: grey }\n"
"th.column-heading-right { text-align: right; " number-header-font-info " }\n" "th.column-heading-left { text-align: left; " number-header-info " }\n"
"td.neg { " (if negative-red? "color: red; " "") " }\n" "th.column-heading-center { text-align: center; " number-header-info " }\n"
"td.number-cell, td.total-number-cell { text-align: right; white-space: nowrap; }\n" "th.column-heading-right { text-align: right; " number-header-info " }\n"
"td.date-cell { white-space: nowrap; }\n" "td.neg { " (if negative-red? "color: red; " "") " }\n"
"td.anchor-cell { white-space: nowrap; " text-cell-font-info " }\n" "td.number-cell, td.total-number-cell { text-align: right; white-space: nowrap; }\n"
"td.number-cell { " number-cell-font-info " }\n" "td.date-cell { white-space: nowrap; }\n"
"td.number-header { text-align: right; " number-header-font-info " }\n" "td.anchor-cell { white-space: nowrap; " text-cell-info " }\n"
"td.text-cell { " text-cell-font-info " }\n" "td.number-cell { " number-cell-info " }\n"
"td.total-number-cell { " total-number-cell-font-info " }\n" "td.number-header { text-align: right; " number-header-info " }\n"
"td.total-label-cell { " total-label-cell-font-info " }\n" "td.text-cell { " text-cell-info " }\n"
"td.centered-label-cell { text-align: center; " centered-label-cell-font-info " }\n" "td.total-number-cell { " total-number-cell-info " }\n"
(or (gnc:html-document-style-text doc) "") "td.total-label-cell { " total-label-cell-info " }\n"
) "td.centered-label-cell { text-align: center; " centered-label-cell-info " }\n"
) (or (gnc:html-document-style-text doc) "")))))
)
)

View File

@ -247,6 +247,8 @@
(define (add-owner-table table splits acc start-date end-date date-type (define (add-owner-table table splits acc start-date end-date date-type
used-columns payable? link-option) used-columns payable? link-option)
(define (AP-negate num)
(if payable? (- num) num))
(define currency (xaccAccountGetCommodity acc)) (define currency (xaccAccountGetCommodity acc))
(define link-cols (assq-ref '((none . 0) (simple . 1) (detailed . 3)) link-option)) (define link-cols (assq-ref '((none . 0) (simple . 1) (detailed . 3)) link-option))
(define (print-totals total debit credit tax sale) (define (print-totals total debit credit tax sale)
@ -313,8 +315,9 @@
(cons (list (gnc:make-html-table-cell/size 1 2 (_ "Outstanding")) (cons (list (gnc:make-html-table-cell/size 1 2 (_ "Outstanding"))
(make-cell (make-cell
(gnc:make-gnc-monetary (gnc:make-gnc-monetary
currency (gnc-lot-get-balance currency
(gncInvoiceGetPostedLot invoice))))) (AP-negate (gnc-lot-get-balance
(gncInvoiceGetPostedLot invoice))))))
result)))) result))))
(else (else
(let* ((lot-split (car invoice-splits)) (let* ((lot-split (car invoice-splits))
@ -328,7 +331,7 @@
(let* ((tfr-split (car tfr-splits)) (let* ((tfr-split (car tfr-splits))
(tfr-acct (xaccSplitGetAccount tfr-split)) (tfr-acct (xaccSplitGetAccount tfr-split))
(tfr-curr (xaccAccountGetCommodity tfr-acct)) (tfr-curr (xaccAccountGetCommodity tfr-acct))
(tfr-amt (xaccSplitGetAmount tfr-split))) (tfr-amt (AP-negate (xaccSplitGetAmount tfr-split))))
(lp1 (cdr tfr-splits) (lp1 (cdr tfr-splits)
(cons (list (cons (list
(qof-print-date (xaccTransGetDate lot-txn)) (qof-print-date (xaccTransGetDate lot-txn))
@ -371,7 +374,7 @@
(let* ((payment-split (car payment-splits)) (let* ((payment-split (car payment-splits))
(inv (car payment-split)) (inv (car payment-split))
(inv-split (cadr payment-split)) (inv-split (cadr payment-split))
(inv-amount (xaccSplitGetAmount inv-split))) (inv-amount (AP-negate (xaccSplitGetAmount inv-split))))
(lp (cdr payment-splits) (lp (cdr payment-splits)
(- amount inv-amount) (- amount inv-amount)
(cons (list (cons (list

View File

@ -349,6 +349,12 @@
'("-$23.00") '("-$23.00")
(get-row-col sxml -1 -1))) (get-row-col sxml -1 -1)))
(set-option! options "Filter" "Transaction Filter excludes matched strings" #t)
(let ((sxml (options->sxml options "negate transaction filter not.s?")))
(test-equal "transaction filter in bank to 'not.s?' and switch regex, sum = -$23.00"
'("$24.00")
(get-row-col sxml -1 -1)))
;; Test Reconcile Status Filters ;; Test Reconcile Status Filters
(set! options (default-testing-options)) (set! options (default-testing-options))
(set-option! options "General" "Start Date" (cons 'absolute (gnc-dmy2time64 01 01 1969))) (set-option! options "General" "Start Date" (cons 'absolute (gnc-dmy2time64 01 01 1969)))

View File

@ -213,7 +213,7 @@
(let ((headline (or (gnc:html-document-headline doc) (let ((headline (or (gnc:html-document-headline doc)
(gnc:html-document-title doc)))) (gnc:html-document-title doc))))
(if headline (if (and headline (not (equal? headline "")))
(gnc:html-document-add-object! (gnc:html-document-add-object!
ssdoc ssdoc
(gnc:make-html-text (gnc:make-html-text

View File

@ -45,7 +45,8 @@
) )
(define html-doc-header-no-title (define html-doc-header-no-title
"<html dir='auto'>\n\ "<!DOCTYPE html>
<html dir='auto'>\n\
<head>\n\ <head>\n\
<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n\ <meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n\
</head><body>") </head><body>")
@ -87,7 +88,8 @@
(gnc:html-document-set-title! test-doc "HTML Document Title") (gnc:html-document-set-title! test-doc "HTML Document Title")
(test-equal "HTML Document - Render with title" (test-equal "HTML Document - Render with title"
"<html dir='auto'>\n\ "<!DOCTYPE html>
<html dir='auto'>\n\
<head>\n\ <head>\n\
<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n\ <meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n\
<title>\n\ <title>\n\

View File

@ -89,6 +89,8 @@
(define optname-transaction-matcher (N_ "Transaction Filter")) (define optname-transaction-matcher (N_ "Transaction Filter"))
(define optname-transaction-matcher-regex (define optname-transaction-matcher-regex
(N_ "Use regular expressions for transaction filter")) (N_ "Use regular expressions for transaction filter"))
(define optname-transaction-matcher-exclude
(N_ "Transaction Filter excludes matched strings"))
(define optname-reconcile-status (N_ "Reconcile Status")) (define optname-reconcile-status (N_ "Reconcile Status"))
(define optname-void-transactions (N_ "Void Transactions")) (define optname-void-transactions (N_ "Void Transactions"))
(define optname-closing-transactions (N_ "Closing transactions")) (define optname-closing-transactions (N_ "Closing transactions"))
@ -604,6 +606,13 @@ enable full POSIX regular expressions capabilities. '#work|#family' will match b
tags within description, notes or memo. ") tags within description, notes or memo. ")
#f)) #f))
(gnc:register-trep-option
(gnc:make-simple-boolean-option
pagename-filter optname-transaction-matcher-exclude
"i3"
(_ "If this option is selected, transactions matching filter are excluded.")
#f))
(gnc:register-trep-option (gnc:register-trep-option
(gnc:make-multichoice-option (gnc:make-multichoice-option
pagename-filter optname-reconcile-status pagename-filter optname-reconcile-status
@ -1969,6 +1978,8 @@ be excluded from periodic reporting.")
(lambda () (make-regexp transaction-matcher)) (lambda () (make-regexp transaction-matcher))
(const 'invalid-transaction-regex)) (const 'invalid-transaction-regex))
'no-guile-regex-support))) 'no-guile-regex-support)))
(transaction-filter-exclude?
(opt-val pagename-filter optname-transaction-matcher-exclude))
(reconcile-status-filter (reconcile-status-filter
(keylist-get-info reconcile-status-list (keylist-get-info reconcile-status-list
(opt-val pagename-filter optname-reconcile-status) (opt-val pagename-filter optname-reconcile-status)
@ -2044,6 +2055,11 @@ be excluded from periodic reporting.")
(define (date-comparator? X Y) (define (date-comparator? X Y)
(generic-less? X Y 'date 'none #t)) (generic-less? X Y 'date 'none #t))
(define (transaction-filter-match split)
(or (match? (xaccTransGetDescription (xaccSplitGetParent split)))
(match? (xaccTransGetNotes (xaccSplitGetParent split)))
(match? (xaccSplitGetMemo split))))
(cond (cond
((or (null? c_account_1) ((or (null? c_account_1)
(symbol? account-matcher-regexp) (symbol? account-matcher-regexp)
@ -2129,9 +2145,9 @@ be excluded from periodic reporting.")
((include) (is-filter-member split c_account_2)) ((include) (is-filter-member split c_account_2))
((exclude) (not (is-filter-member split c_account_2)))) ((exclude) (not (is-filter-member split c_account_2))))
(or (string-null? transaction-matcher) (or (string-null? transaction-matcher)
(match? (xaccTransGetDescription trans)) (if transaction-filter-exclude?
(match? (xaccTransGetNotes trans)) (not (transaction-filter-match split))
(match? (xaccSplitGetMemo split))) (transaction-filter-match split)))
(or (not custom-split-filter) (or (not custom-split-filter)
(custom-split-filter split))))) (custom-split-filter split)))))
splits)) splits))

View File

@ -207,7 +207,7 @@ account_id_handler (xmlNodePtr node, gpointer act_pdata)
xaccAccountSetGUID (pdata->account, guid); xaccAccountSetGUID (pdata->account, guid);
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }
@ -384,7 +384,7 @@ account_parent_handler (xmlNodePtr node, gpointer act_pdata)
gnc_account_append_child (parent, pdata->account); gnc_account_append_child (parent, pdata->account);
g_free (gid); guid_free (gid);
return TRUE; return TRUE;
} }

View File

@ -279,7 +279,7 @@ set_parent_child (xmlNodePtr node, struct billterm_pdata* pdata,
gncBillTermSetGUID (term, guid); gncBillTermSetGUID (term, guid);
gncBillTermCommitEdit (term); gncBillTermCommitEdit (term);
} }
g_free (guid); guid_free (guid);
g_return_val_if_fail (term, FALSE); g_return_val_if_fail (term, FALSE);
func (pdata->term, term); func (pdata->term, term);
@ -318,7 +318,7 @@ billterm_guid_handler (xmlNodePtr node, gpointer billterm_pdata)
gncBillTermSetGUID (pdata->term, guid); gncBillTermSetGUID (pdata->term, guid);
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -121,7 +121,7 @@ book_id_handler (xmlNodePtr node, gpointer book_pdata)
guid = dom_tree_to_guid (node); guid = dom_tree_to_guid (node);
qof_instance_set_guid (QOF_INSTANCE (book), guid); qof_instance_set_guid (QOF_INSTANCE (book), guid);
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -109,7 +109,7 @@ budget_id_handler (xmlNodePtr node, gpointer bgt)
guid = dom_tree_to_guid (node); guid = dom_tree_to_guid (node);
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
qof_instance_set_guid (QOF_INSTANCE (bgt), guid); qof_instance_set_guid (QOF_INSTANCE (bgt), guid);
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -205,7 +205,7 @@ customer_guid_handler (xmlNodePtr node, gpointer cust_pdata)
gncCustomerSetGUID (pdata->customer, guid); gncCustomerSetGUID (pdata->customer, guid);
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }
@ -237,7 +237,7 @@ customer_terms_handler (xmlNodePtr node, gpointer cust_pdata)
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
term = gnc_billterm_xml_find_or_create (pdata->book, guid); term = gnc_billterm_xml_find_or_create (pdata->book, guid);
g_assert (term); g_assert (term);
g_free (guid); guid_free (guid);
gncCustomerSetTerms (pdata->customer, term); gncCustomerSetTerms (pdata->customer, term);
return TRUE; return TRUE;
@ -353,7 +353,7 @@ customer_taxtable_handler (xmlNodePtr node, gpointer cust_pdata)
gncTaxTableDecRef (taxtable); gncTaxTableDecRef (taxtable);
gncCustomerSetTaxTable (pdata->customer, taxtable); gncCustomerSetTaxTable (pdata->customer, taxtable);
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -178,7 +178,7 @@ employee_guid_handler (xmlNodePtr node, gpointer employee_pdata)
gncEmployeeSetGUID (pdata->employee, guid); gncEmployeeSetGUID (pdata->employee, guid);
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }
@ -282,7 +282,7 @@ employee_ccard_handler (xmlNodePtr node, gpointer employee_pdata)
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
ccard_acc = xaccAccountLookup (guid, pdata->book); ccard_acc = xaccAccountLookup (guid, pdata->book);
g_free (guid); guid_free (guid);
g_return_val_if_fail (ccard_acc, FALSE); g_return_val_if_fail (ccard_acc, FALSE);
gncEmployeeSetCCard (pdata->employee, ccard_acc); gncEmployeeSetCCard (pdata->employee, ccard_acc);

View File

@ -283,7 +283,7 @@ set_account (xmlNodePtr node, struct entry_pdata* pdata,
guid = dom_tree_to_guid (node); guid = dom_tree_to_guid (node);
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
acc = xaccAccountLookup (guid, pdata->book); acc = xaccAccountLookup (guid, pdata->book);
g_free (guid); guid_free (guid);
g_return_val_if_fail (acc, FALSE); g_return_val_if_fail (acc, FALSE);
if (func) if (func)
@ -314,7 +314,7 @@ set_taxtable (xmlNodePtr node, struct entry_pdata* pdata,
gncTaxTableDecRef (taxtable); gncTaxTableDecRef (taxtable);
func (pdata->entry, taxtable); func (pdata->entry, taxtable);
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }
@ -339,7 +339,7 @@ entry_guid_handler (xmlNodePtr node, gpointer entry_pdata)
gncEntrySetGUID (pdata->entry, guid); gncEntrySetGUID (pdata->entry, guid);
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }
@ -579,7 +579,7 @@ entry_order_handler (xmlNodePtr node, gpointer entry_pdata)
gncOrderAddEntry (order, pdata->entry); gncOrderAddEntry (order, pdata->entry);
gncOrderCommitEdit (order); gncOrderCommitEdit (order);
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }
@ -604,7 +604,7 @@ entry_invoice_handler (xmlNodePtr node, gpointer entry_pdata)
gncInvoiceAddEntry (invoice, pdata->entry); gncInvoiceAddEntry (invoice, pdata->entry);
gncInvoiceCommitEdit (invoice); gncInvoiceCommitEdit (invoice);
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }
@ -629,7 +629,7 @@ entry_bill_handler (xmlNodePtr node, gpointer entry_pdata)
gncBillAddEntry (invoice, pdata->entry); gncBillAddEntry (invoice, pdata->entry);
gncInvoiceCommitEdit (invoice); gncInvoiceCommitEdit (invoice);
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -214,7 +214,7 @@ invoice_guid_handler (xmlNodePtr node, gpointer invoice_pdata)
gncInvoiceSetGUID (pdata->invoice, guid); gncInvoiceSetGUID (pdata->invoice, guid);
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }
@ -296,7 +296,7 @@ invoice_terms_handler (xmlNodePtr node, gpointer invoice_pdata)
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
term = gnc_billterm_xml_find_or_create (pdata->book, guid); term = gnc_billterm_xml_find_or_create (pdata->book, guid);
g_assert (term); g_assert (term);
g_free (guid); guid_free (guid);
gncInvoiceSetTerms (pdata->invoice, term); gncInvoiceSetTerms (pdata->invoice, term);
return TRUE; return TRUE;
@ -312,7 +312,7 @@ invoice_posttxn_handler (xmlNodePtr node, gpointer invoice_pdata)
guid = dom_tree_to_guid (node); guid = dom_tree_to_guid (node);
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
txn = xaccTransLookup (guid, pdata->book); txn = xaccTransLookup (guid, pdata->book);
g_free (guid); guid_free (guid);
g_return_val_if_fail (txn, FALSE); g_return_val_if_fail (txn, FALSE);
gncInvoiceSetPostedTxn (pdata->invoice, txn); gncInvoiceSetPostedTxn (pdata->invoice, txn);
@ -329,7 +329,7 @@ invoice_postlot_handler (xmlNodePtr node, gpointer invoice_pdata)
guid = dom_tree_to_guid (node); guid = dom_tree_to_guid (node);
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
lot = gnc_lot_lookup (guid, pdata->book); lot = gnc_lot_lookup (guid, pdata->book);
g_free (guid); guid_free (guid);
g_return_val_if_fail (lot, FALSE); g_return_val_if_fail (lot, FALSE);
gncInvoiceSetPostedLot (pdata->invoice, lot); gncInvoiceSetPostedLot (pdata->invoice, lot);
@ -346,7 +346,7 @@ invoice_postacc_handler (xmlNodePtr node, gpointer invoice_pdata)
guid = dom_tree_to_guid (node); guid = dom_tree_to_guid (node);
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
acc = xaccAccountLookup (guid, pdata->book); acc = xaccAccountLookup (guid, pdata->book);
g_free (guid); guid_free (guid);
g_return_val_if_fail (acc, FALSE); g_return_val_if_fail (acc, FALSE);
gncInvoiceSetPostedAcc (pdata->invoice, acc); gncInvoiceSetPostedAcc (pdata->invoice, acc);

View File

@ -146,7 +146,7 @@ job_guid_handler (xmlNodePtr node, gpointer job_pdata)
gncJobSetGUID (pdata->job, guid); gncJobSetGUID (pdata->job, guid);
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -91,7 +91,7 @@ lot_id_handler (xmlNodePtr node, gpointer p)
guid = dom_tree_to_guid (node); guid = dom_tree_to_guid (node);
gnc_lot_set_guid (pdata->lot, *guid); gnc_lot_set_guid (pdata->lot, *guid);
g_free (guid); guid_free (guid);
LEAVE (""); LEAVE ("");
return TRUE; return TRUE;

View File

@ -161,7 +161,7 @@ order_guid_handler (xmlNodePtr node, gpointer order_pdata)
gncOrderSetGUID (pdata->order, guid); gncOrderSetGUID (pdata->order, guid);
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -182,11 +182,11 @@ owner_id_handler (xmlNodePtr node, gpointer owner_pdata)
} }
default: default:
PWARN ("Invalid owner type: %d\n", gncOwnerGetType (pdata->owner)); PWARN ("Invalid owner type: %d\n", gncOwnerGetType (pdata->owner));
g_free (guid); guid_free (guid);
return FALSE; return FALSE;
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -97,7 +97,7 @@ price_parse_xml_sub_node (GNCPrice* p, xmlNodePtr sub_node, QofBook* book)
GncGUID* c = dom_tree_to_guid (sub_node); GncGUID* c = dom_tree_to_guid (sub_node);
if (!c) return FALSE; if (!c) return FALSE;
gnc_price_set_guid (p, c); gnc_price_set_guid (p, c);
g_free (c); guid_free (c);
} }
else if (g_strcmp0 ("price:commodity", (char*)sub_node->name) == 0) else if (g_strcmp0 ("price:commodity", (char*)sub_node->name) == 0)
{ {

View File

@ -593,7 +593,7 @@ sx_templ_acct_handler (xmlNodePtr node, gpointer sx_pdata)
account = xaccAccountLookup (templ_acct_guid, pdata->book); account = xaccAccountLookup (templ_acct_guid, pdata->book);
sx_set_template_account (sx, account); sx_set_template_account (sx, account);
g_free (templ_acct_guid); guid_free (templ_acct_guid);
return TRUE; return TRUE;
} }

View File

@ -155,7 +155,7 @@ ttentry_acct_handler (xmlNodePtr node, gpointer ttentry_pdata)
guid = dom_tree_to_guid (node); guid = dom_tree_to_guid (node);
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
acc = xaccAccountLookup (guid, pdata->book); acc = xaccAccountLookup (guid, pdata->book);
g_free (guid); guid_free (guid);
g_return_val_if_fail (acc, FALSE); g_return_val_if_fail (acc, FALSE);
gncTaxTableEntrySetAccount (pdata->ttentry, acc); gncTaxTableEntrySetAccount (pdata->ttentry, acc);
@ -257,7 +257,7 @@ set_parent_child (xmlNodePtr node, struct taxtable_pdata* pdata,
gncTaxTableSetGUID (table, guid); gncTaxTableSetGUID (table, guid);
gncTaxTableCommitEdit (table); gncTaxTableCommitEdit (table);
} }
g_free (guid); guid_free (guid);
g_return_val_if_fail (table, FALSE); g_return_val_if_fail (table, FALSE);
func (pdata->table, table); func (pdata->table, table);
@ -285,7 +285,7 @@ taxtable_guid_handler (xmlNodePtr node, gpointer taxtable_pdata)
gncTaxTableSetGUID (pdata->table, guid); gncTaxTableSetGUID (pdata->table, guid);
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -237,7 +237,7 @@ spl_id_handler (xmlNodePtr node, gpointer data)
xaccSplitSetGUID (pdata->split, tmp); xaccSplitSetGUID (pdata->split, tmp);
g_free (tmp); guid_free (tmp);
return TRUE; return TRUE;
} }
@ -316,7 +316,7 @@ spl_account_handler (xmlNodePtr node, gpointer data)
xaccAccountInsertSplit (account, pdata->split); xaccAccountInsertSplit (account, pdata->split);
g_free (id); guid_free (id);
return TRUE; return TRUE;
} }
@ -340,7 +340,7 @@ spl_lot_handler (xmlNodePtr node, gpointer data)
gnc_lot_add_split (lot, pdata->split); gnc_lot_add_split (lot, pdata->split);
g_free (id); guid_free (id);
return TRUE; return TRUE;
} }
@ -455,7 +455,7 @@ trn_id_handler (xmlNodePtr node, gpointer trans_pdata)
xaccTransSetGUID ((Transaction*)trn, tmp); xaccTransSetGUID ((Transaction*)trn, tmp);
g_free (tmp); guid_free (tmp);
return TRUE; return TRUE;
} }

View File

@ -190,7 +190,7 @@ vendor_guid_handler (xmlNodePtr node, gpointer vendor_pdata)
gncVendorSetGUID (pdata->vendor, guid); gncVendorSetGUID (pdata->vendor, guid);
} }
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }
@ -222,7 +222,7 @@ vendor_terms_handler (xmlNodePtr node, gpointer vendor_pdata)
g_return_val_if_fail (guid, FALSE); g_return_val_if_fail (guid, FALSE);
term = gnc_billterm_xml_find_or_create (pdata->book, guid); term = gnc_billterm_xml_find_or_create (pdata->book, guid);
g_assert (term); g_assert (term);
g_free (guid); guid_free (guid);
gncVendorSetTerms (pdata->vendor, term); gncVendorSetTerms (pdata->vendor, term);
return TRUE; return TRUE;
@ -298,7 +298,7 @@ vendor_taxtable_handler (xmlNodePtr node, gpointer vendor_pdata)
gncTaxTableDecRef (taxtable); gncTaxTableDecRef (taxtable);
gncVendorSetTaxTable (pdata->vendor, taxtable); gncVendorSetTaxTable (pdata->vendor, taxtable);
g_free (guid); guid_free (guid);
return TRUE; return TRUE;
} }

View File

@ -251,7 +251,7 @@ test_dom_tree_to_guid (void)
xmlFreeNode (test_node); xmlFreeNode (test_node);
g_free (test_guid1); g_free (test_guid1);
g_free (test_guid2); guid_free (test_guid2);
} }
} }

View File

@ -209,12 +209,12 @@ equals_node_val_vs_guid (xmlNodePtr node, const GncGUID* id)
if (guid_compare (cmpid, id) == 0) if (guid_compare (cmpid, id) == 0)
{ {
g_free (cmpid); guid_free (cmpid);
return TRUE; return TRUE;
} }
else else
{ {
g_free (cmpid); guid_free (cmpid);
return FALSE; return FALSE;
} }
} }

View File

@ -90,7 +90,7 @@ find_appropriate_node (xmlNodePtr node, Split* spl)
{ {
account_guid_good = TRUE; account_guid_good = TRUE;
} }
g_free (accid); guid_free (accid);
} }
if (account_guid_good && amount_good) if (account_guid_good && amount_good)
@ -116,10 +116,10 @@ equals_node_val_vs_split_internal (xmlNodePtr node, Split* spl)
if (!guid_equal (id, xaccSplitGetGUID (spl))) if (!guid_equal (id, xaccSplitGetGUID (spl)))
{ {
g_free (id); guid_free (id);
return "ids differ"; return "ids differ";
} }
g_free (id); guid_free (id);
} }
else if (g_strcmp0 ((char*)mark->name, "split:memo") == 0) else if (g_strcmp0 ((char*)mark->name, "split:memo") == 0)
{ {
@ -191,10 +191,10 @@ equals_node_val_vs_split_internal (xmlNodePtr node, Split* spl)
if (!guid_equal (id, xaccAccountGetGUID (account))) if (!guid_equal (id, xaccAccountGetGUID (account)))
{ {
g_free (id); guid_free (id);
return "accounts differ"; return "accounts differ";
} }
g_free (id); guid_free (id);
} }
} }
return NULL; return NULL;

View File

@ -211,14 +211,14 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; flattens an arbitrary deep nested list into simple list. this is ;; flattens an arbitrary deep nested list into simple list. this is
;; probably the most efficient algorithm available. '(1 2 (3 4)) --> ;; probably the most efficient algorithm available. '(1 2 (3 4)) -->
;; '(1 2 3 4) ;; '(1 2 3 4) thanks to manumanumanu on #guile
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (gnc:list-flatten . lst) (define (gnc:list-flatten . lst)
(reverse (let loop ((lst lst) (acc '()))
(let lp ((e lst) (accum '())) (cond
(if (list? e) ((null? lst) acc)
(fold lp accum e) ((pair? lst) (loop (car lst) (loop (cdr lst) acc)))
(cons e accum))))) (else (cons lst acc)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; compatibility hack for fixing guile-2.0 string handling. this code ;; compatibility hack for fixing guile-2.0 string handling. this code