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"
enum {
PROP_0,
PROP_USE_BUTTONS,
PROP_0,
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,
guint param_id,
const GValue *value,
GParamSpec *pspec);
static void gcrd_set_property (GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec);
static void gcrd_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec);
static void gcrd_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec);
static void gcrd_today_clicked (GtkWidget *button,
GncCellRendererDate *cell);
static void gcrd_today_clicked (GtkWidget *button,
GncCellRendererDate *cell);
static void gcrd_selected_double_click (GtkWidget *calendar,
GncCellRendererDate *cell);
static void gcrd_selected_double_click (GtkWidget *calendar,
GncCellRendererDate *cell);
static void gcrd_cancel_clicked (GtkWidget *popup_window,
GncCellRendererDate *cell);
static void gcrd_cancel_clicked (GtkWidget *popup_window,
GncCellRendererDate *cell);
static void gcrd_ok_clicked (GtkWidget *popup_window,
GncCellRendererDate *cell);
static void gcrd_ok_clicked (GtkWidget *popup_window,
GncCellRendererDate *cell);
static void gcrd_day_selected (GtkWidget *popup_window,
GncCellRendererDate *cell);
static void gcrd_day_selected (GtkWidget *popup_window,
GncCellRendererDate *cell);
GtkCellEditable *gcrd_start_editing (GtkCellRenderer *cell,
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
GtkCellEditable *gcrd_start_editing (GtkCellRenderer *cell,
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags);
static void gcrd_show (GncCellRendererPopup *cell,
const gchar *path,
gint x1,
gint y1,
gint x2,
gint y2);
static void gcrd_hide (GncCellRendererPopup *cell);
static void gcrd_show (GncCellRendererPopup *cell,
const gchar *path,
gint x1,
gint y1,
gint x2,
gint y2);
static void gcrd_hide (GncCellRendererPopup *cell);
/* These two functions are used internally */
@ -104,329 +105,318 @@ static GncCellRendererPopupClass *parent_class;
GType
gnc_cell_renderer_date_get_type (void)
{
static GType cell_text_type = 0;
if (!cell_text_type) {
static const GTypeInfo cell_text_info = {
sizeof (GncCellRendererDateClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gcrd_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GncCellRendererDate),
0, /* n_preallocs */
(GInstanceInitFunc) gcrd_init,
};
cell_text_type = g_type_register_static (GNC_TYPE_CELL_RENDERER_POPUP,
"GncCellRendererDate",
&cell_text_info,
0);
}
return cell_text_type;
static GType cell_text_type = 0;
if (!cell_text_type) {
static const GTypeInfo cell_text_info = {
sizeof (GncCellRendererDateClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gcrd_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GncCellRendererDate),
0, /* n_preallocs */
(GInstanceInitFunc) gcrd_init,
};
cell_text_type = g_type_register_static (GNC_TYPE_CELL_RENDERER_POPUP,
"GncCellRendererDate",
&cell_text_info,
0);
}
return cell_text_type;
}
static void
gcrd_init (GncCellRendererDate *date)
{
GncCellRendererPopup *popup;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *button;
GncCellRendererPopup *popup;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *button;
popup = GNC_CELL_RENDERER_POPUP (date);
popup = GNC_CELL_RENDERER_POPUP(date);
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (popup->popup_window), frame);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER(popup->popup_window), frame);
gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_OUT);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_box_set_homogeneous (GTK_BOX (vbox), FALSE);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_box_set_homogeneous (GTK_BOX(vbox), FALSE);
gtk_container_add (GTK_CONTAINER (frame), vbox);
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);
gtk_container_add (GTK_CONTAINER(frame), vbox);
gtk_container_set_border_width (GTK_CONTAINER(vbox), 6);
date->button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_box_set_spacing (GTK_BOX (date->button_box), 6);
gtk_box_pack_start (GTK_BOX (vbox), date->button_box, FALSE, FALSE, 0);
date->calendar = gtk_calendar_new ();
popup->focus_window = date->calendar;
gtk_box_pack_start (GTK_BOX(vbox), date->calendar, TRUE, TRUE, 0);
button = gtk_button_new_with_label (_("Cancel"));
gtk_container_add (GTK_CONTAINER (date->button_box), button);
g_signal_connect (button, "clicked",
G_CALLBACK (gcrd_cancel_clicked),
date);
date->button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_box_set_spacing (GTK_BOX(date->button_box), 6);
gtk_box_pack_start (GTK_BOX(vbox), date->button_box, FALSE, FALSE, 0);
date->today_button = gtk_button_new_with_label (_("Today"));
gtk_container_add (GTK_CONTAINER (date->button_box), date->today_button);
g_signal_connect (date->today_button, "clicked",
G_CALLBACK (gcrd_today_clicked),
date);
button = gtk_button_new_with_label (_("Cancel"));
gtk_container_add (GTK_CONTAINER(date->button_box), button);
g_signal_connect (button, "clicked",
G_CALLBACK(gcrd_cancel_clicked),
date);
button = gtk_button_new_with_label (_("Select"));
gtk_container_add (GTK_CONTAINER (date->button_box), button);
g_signal_connect (button, "clicked",
G_CALLBACK (gcrd_ok_clicked),
date);
date->today_button = gtk_button_new_with_label (_("Today"));
gtk_container_add (GTK_CONTAINER(date->button_box), date->today_button);
g_signal_connect (date->today_button, "clicked",
G_CALLBACK(gcrd_today_clicked),
date);
g_signal_connect (date->calendar, "day-selected",
G_CALLBACK (gcrd_day_selected),
date);
g_signal_connect (date->calendar, "day-selected-double-click",
G_CALLBACK (gcrd_selected_double_click),
date);
button = gtk_button_new_with_label (_("Select"));
gtk_container_add (GTK_CONTAINER(date->button_box), button);
g_signal_connect (button, "clicked",
G_CALLBACK(gcrd_ok_clicked),
date);
//Set calendar to show current date when displayed
date->time = gnc_time (NULL);
g_signal_connect (date->calendar, "day-selected",
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
gcrd_class_init (GncCellRendererDateClass *klass)
{
GncCellRendererPopupClass *popup_class;
GtkCellRendererClass *cell_class;
GObjectClass *gobject_class;
GncCellRendererPopupClass *popup_class;
GtkCellRendererClass *cell_class;
GObjectClass *gobject_class;
popup_class = GNC_CELL_RENDERER_POPUP_CLASS (klass);
cell_class = GTK_CELL_RENDERER_CLASS (klass);
parent_class = GNC_CELL_RENDERER_POPUP_CLASS (g_type_class_peek_parent (klass));
gobject_class = G_OBJECT_CLASS (klass);
popup_class = GNC_CELL_RENDERER_POPUP_CLASS(klass);
cell_class = GTK_CELL_RENDERER_CLASS(klass);
parent_class = GNC_CELL_RENDERER_POPUP_CLASS(g_type_class_peek_parent (klass));
gobject_class = G_OBJECT_CLASS(klass);
gobject_class->set_property = gcrd_set_property;
gobject_class->get_property = gcrd_get_property;
gobject_class->set_property = gcrd_set_property;
gobject_class->get_property = gcrd_get_property;
cell_class->start_editing = gcrd_start_editing;
popup_class->show_popup = gcrd_show;
popup_class->hide_popup = gcrd_hide;
cell_class->start_editing = gcrd_start_editing;
g_object_class_install_property (
gobject_class,
popup_class->show_popup = gcrd_show;
popup_class->hide_popup = gcrd_hide;
g_object_class_install_property (
gobject_class,
PROP_USE_BUTTONS,
g_param_spec_boolean ("use-buttons",
NULL,
NULL,
TRUE,
G_PARAM_READWRITE));
NULL,
NULL,
TRUE,
G_PARAM_READWRITE));
}
static void
gcrd_set_property (GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec)
guint param_id,
const GValue *value,
GParamSpec *pspec)
{
GncCellRendererDate *date;
GncCellRendererDate *date = GNC_CELL_RENDERER_DATE(object);
date = GNC_CELL_RENDERER_DATE (object);
switch (param_id) {
case PROP_USE_BUTTONS:
date->use_buttons = g_value_get_boolean (value);
switch (param_id)
{
case PROP_USE_BUTTONS:
date->use_buttons = g_value_get_boolean (value);
if (date->use_buttons)
gtk_widget_show (date->button_box);
else
gtk_widget_hide (date->button_box);
break;
if (date->use_buttons)
gtk_widget_show (date->button_box);
else
gtk_widget_hide (date->button_box);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
}
}
static void
gcrd_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec)
guint param_id,
GValue *value,
GParamSpec *pspec)
{
GncCellRendererDate *date;
GncCellRendererDate *date = GNC_CELL_RENDERER_DATE (object);
date = GNC_CELL_RENDERER_DATE (object);
switch (param_id) {
case PROP_USE_BUTTONS:
g_value_set_boolean (value, date->use_buttons);
break;
switch (param_id)
{
case PROP_USE_BUTTONS:
g_value_set_boolean (value, date->use_buttons);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
}
}
GtkCellEditable *
gcrd_start_editing (GtkCellRenderer *cell,
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
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);
}
GNC_CELL_RENDERER_POPUP(cell)->editing_canceled = FALSE;
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
gcrd_hide (GncCellRendererPopup *cell)
{
if (parent_class->hide_popup) {
parent_class->hide_popup (cell);
}
if (parent_class->hide_popup) {
parent_class->hide_popup (cell);
}
}
static void
gcrd_show (GncCellRendererPopup *cell,
const gchar *path,
gint x1,
gint y1,
gint x2,
gint y2)
const gchar *path,
gint x1,
gint y1,
gint x2,
gint y2)
{
GncCellRendererDate *date;
gint year = 0;
gint month = 0;
gint day = 0;
const gchar *text;
GncCellRendererDate *date = GNC_CELL_RENDERER_DATE (cell);
gint year = 0;
gint month = 0;
gint day = 0;
const gchar *text;
if (parent_class->show_popup) {
parent_class->show_popup (cell,
path,
x1, y1,
x2, y2);
}
if (parent_class->show_popup) {
parent_class->show_popup (cell,
path,
x1, y1,
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, "")))
{
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_month (GTK_CALENDAR(date->calendar), month - 1, year);
gtk_calendar_clear_marks (GTK_CALENDAR (date->calendar));
gtk_calendar_select_month (GTK_CALENDAR (date->calendar), month - 1, year);
gtk_calendar_select_day (GTK_CALENDAR (date->calendar), day);
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 *
gnc_cell_renderer_date_new (gboolean use_buttons)
{
GObject *cell;
GObject *cell;
cell = g_object_new (GNC_TYPE_CELL_RENDERER_DATE,
"use-buttons", use_buttons,
NULL);
return GTK_CELL_RENDERER (cell);
cell = g_object_new (GNC_TYPE_CELL_RENDERER_DATE,
"use-buttons", use_buttons,
NULL);
return GTK_CELL_RENDERER(cell);
}
static void
gcrd_today_clicked (GtkWidget *button, GncCellRendererDate *cell)
{
time64 today;
gint year = 0, month = 0, day = 0;
today = gnc_time (NULL);
time64 today;
gint year = 0, month = 0, day = 0;
gcrd_time2dmy ( today, &day, &month, &year);
gtk_calendar_clear_marks (GTK_CALENDAR (cell->calendar));
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);
today = gnc_time (NULL);
gcrd_time2dmy (today, &day, &month, &year);
gtk_calendar_clear_marks (GTK_CALENDAR(cell->calendar));
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
gcrd_selected_double_click (GtkWidget *calendar, GncCellRendererDate *cell)
{
GncCellRendererPopup *popup;
popup = GNC_CELL_RENDERER_POPUP (cell);
GncCellRendererPopup *popup = GNC_CELL_RENDERER_POPUP(cell);
gcrd_ok_clicked (popup->popup_window, cell);
gcrd_ok_clicked (popup->popup_window, cell);
}
static void
gcrd_cancel_clicked (GtkWidget *popup_window, GncCellRendererDate *cell)
{
GncCellRendererPopup *popup;
popup = GNC_CELL_RENDERER_POPUP (cell);
GncCellRendererPopup *popup = GNC_CELL_RENDERER_POPUP(cell);
popup->editing_canceled = TRUE;
gnc_cell_renderer_popup_hide (popup);
popup->editing_canceled = TRUE;
gnc_cell_renderer_popup_hide (popup);
}
static void
gcrd_ok_clicked (GtkWidget *popup_window, GncCellRendererDate *cell)
{
GncCellRendererPopup *popup;
popup = GNC_CELL_RENDERER_POPUP (cell);
GncCellRendererPopup *popup = GNC_CELL_RENDERER_POPUP(cell);
gcrd_day_selected (popup_window, cell);
gcrd_day_selected (popup_window, cell);
popup->editing_canceled = FALSE;
gnc_cell_renderer_popup_hide (popup);
popup->editing_canceled = FALSE;
gnc_cell_renderer_popup_hide (popup);
}
static void
gcrd_day_selected (GtkWidget *popup_window, GncCellRendererDate *cell)
{
guint year;
guint month;
guint day;
time64 t;
gchar *str;
guint year;
guint month;
guint day;
time64 t;
gchar *str;
gtk_calendar_get_date (GTK_CALENDAR (cell->calendar),
&year,
&month,
&day);
gtk_calendar_get_date (GTK_CALENDAR(cell->calendar),
&year,
&month,
&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 (GNC_CELL_RENDERER_POPUP (cell)->editable), str);
g_free (str);
gnc_popup_entry_set_text (
GNC_POPUP_ENTRY(GNC_CELL_RENDERER_POPUP(cell)->editable), str);
g_free (str);
}
@ -435,7 +425,7 @@ gboolean
gcrd_time2dmy (time64 raw_time, gint *day, gint *month, gint *year)
{
struct tm * timeinfo;
timeinfo = gnc_localtime (&raw_time);
if (timeinfo == NULL)
return FALSE;
@ -460,7 +450,6 @@ gcrd_dmy2time (gint day, gint month, gint year)
return gnc_mktime (&when);
}
/* This function converts a time64 value date to a string */
static gchar *
gcrd_time2dmy_string (time64 raw_time)
@ -468,7 +457,6 @@ gcrd_time2dmy_string (time64 raw_time)
return qof_print_date (raw_time);
}
/* This function converts a string date to a time64 value */
static time64
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))
{
struct tm when;
memset (&when, 0, sizeof (when));
struct tm when;
memset (&when, 0, sizeof (when));
when.tm_year = year - 1900;
when.tm_mon = month - 1 ;
when.tm_mday = day;
@ -487,7 +475,7 @@ gcrd_string_dmy2time (const gchar *date_string)
}
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 gpw_cell_editable_init (GtkCellEditableIface *iface);
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
{
@ -49,6 +59,12 @@ enum
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_EDITING_CANCELED,
};
static GtkEventBoxClass *parent_class;
static guint signals[LAST_SIGNAL];
@ -62,11 +78,11 @@ gnc_popup_entry_get_type (void)
static const GTypeInfo widget_info =
{
sizeof (GncPopupEntryClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gnc_popup_entry_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GncPopupEntry),
0, /* n_preallocs */
(GInstanceInitFunc) gnc_popup_entry_init,
@ -97,12 +113,14 @@ gnc_popup_entry_init (GncPopupEntry *widget)
{
GtkWidget *arrow;
widget->editing_canceled = FALSE;
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);
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);
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);
gtk_widget_show (arrow);
g_signal_connect (G_OBJECT (arrow), "draw",
G_CALLBACK (gnc_draw_arrow_cb), GINT_TO_POINTER(1));
g_signal_connect (G_OBJECT(arrow), "draw",
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->button, FALSE, 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_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_add_events (GTK_WIDGET (widget), GDK_KEY_PRESS_MASK);
gtk_widget_add_events (GTK_WIDGET (widget), GDK_KEY_RELEASE_MASK);
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_RELEASE_MASK);
}
static void
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;
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));
g_object_class_override_property (gobject_class,
PROP_EDITING_CANCELED,
"editing-canceled");
signals[ARROW_CLICKED] = g_signal_new
("arrow-clicked",
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
gpw_arrow_clicked (GtkWidget *button, GncPopupEntry *widget)
{
@ -157,8 +219,8 @@ gpw_arrow_clicked (GtkWidget *button, GncPopupEntry *widget)
static void
gtk_cell_editable_entry_activated (GtkEntry *entry, GncPopupEntry *widget)
{
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget));
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE(widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE(widget));
}
static gboolean
@ -174,8 +236,8 @@ gtk_cell_editable_key_press_event (GtkEntry *entry,
{
widget->editing_canceled = TRUE;
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget));
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE(widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE(widget));
return TRUE;
}
@ -194,7 +256,7 @@ gtk_cell_editable_key_press_event (GtkEntry *entry,
return FALSE;
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 FALSE;
@ -204,7 +266,7 @@ static gboolean
gpw_key_press_event (GtkWidget *box,
GdkEventKey *key_event)
{
GncPopupEntry *widget = GNC_POPUP_ENTRY (box);
GncPopupEntry *widget = GNC_POPUP_ENTRY(box);
GdkEvent tmp_event;
gtk_widget_grab_focus (widget->entry);
@ -213,21 +275,21 @@ gpw_key_press_event (GtkWidget *box,
{
widget->editing_canceled = TRUE;
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget));
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE(widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE(widget));
return TRUE;
}
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;
}
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;
}
@ -239,29 +301,29 @@ gpw_key_press_event (GtkWidget *box,
gtk_widget_event (widget->entry, &tmp_event);
return GTK_WIDGET_CLASS (parent_class)->key_press_event (GTK_WIDGET (widget),
key_event);
return GTK_WIDGET_CLASS (parent_class)->key_press_event (GTK_WIDGET(widget),
key_event);
}
static void
gpw_start_editing (GtkCellEditable *cell_editable,
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",
G_CALLBACK (gtk_cell_editable_entry_activated),
G_CALLBACK(gtk_cell_editable_entry_activated),
widget);
g_signal_connect (G_OBJECT (widget->entry),
g_signal_connect (G_OBJECT(widget->entry),
"key_press_event",
G_CALLBACK (gtk_cell_editable_key_press_event),
G_CALLBACK(gtk_cell_editable_key_press_event),
widget);
g_signal_connect (G_OBJECT (widget->button),
g_signal_connect (G_OBJECT(widget->button),
"clicked",
(GCallback) gpw_arrow_clicked,
(GCallback)gpw_arrow_clicked,
widget);
}
@ -274,17 +336,17 @@ gpw_cell_editable_init (GtkCellEditableIface *iface)
void
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 *
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
@ -299,14 +361,14 @@ gnc_popup_get_button_width (void)
button = gtk_button_new ();
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);
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_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);
void gnc_popup_entry_set_text (GncPopupEntry *popup,
const gchar *text);
const gchar *text);
const gchar *gnc_popup_entry_get_text (GncPopupEntry *popup);

View File

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

View File

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

View File

@ -59,6 +59,8 @@ typedef struct
GtkWidget *sub_label;
gboolean jump_close;
gchar *saved_filter_text;
gint event_handler_id;
}FindAccountDialog;
@ -194,7 +196,7 @@ fill_model (GtkTreeModel *model, Account *account)
}
static void
get_account_info (FindAccountDialog *facc_dialog)
get_account_info (FindAccountDialog *facc_dialog, gboolean use_saved_filter)
{
Account *root;
GList *accts;
@ -214,7 +216,10 @@ get_account_info (FindAccountDialog *facc_dialog)
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 */
model = gtk_tree_view_get_model (GTK_TREE_VIEW(facc_dialog->view));
@ -250,12 +255,55 @@ get_account_info (FindAccountDialog *facc_dialog)
static void
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
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
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->parent = parent;
facc_dialog->saved_filter_text = g_strdup ("");
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
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(" ");
}
@ -410,6 +463,16 @@ close_handler (gpointer user_data)
FindAccountDialog *facc_dialog = user_data;
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));
gtk_widget_destroy (GTK_WIDGET(facc_dialog->window));
LEAVE(" ");

View File

@ -107,7 +107,8 @@
(define (gnc:html-document-tree-collapse . tree)
(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))
(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/receipt.eguile.scm:<html>
(push "<!DOCTYPE html>\n")
(push "<html dir='auto'>\n")
(push "<head>\n")
(push "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n")

View File

@ -60,104 +60,96 @@
;; Registers font options
(define (register-font-options options)
(let*
(
(opt-register
(lambda (opt) (gnc:register-option options opt)))
(font-family (gnc-get-default-report-font-family))
)
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Title") "a" (N_ "Font info for the report title.")
(string-append font-family " Bold 15")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Account link") "b" (N_ "Font info for account name.")
(string-append font-family " Italic 10")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Number cell") "c" (N_ "Font info for regular number cells.")
(string-append font-family " 10")))
(opt-register
(gnc:make-simple-boolean-option
(N_ "Fonts")
(N_ "Negative Values in Red") "d" (N_ "Display negative values in red.")
#t))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Number header") "e" (N_ "Font info for number headers.")
(string-append font-family " 10")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Text cell") "f" (N_ "Font info for regular text cells.")
(string-append font-family " 10")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Total number cell") "g" (N_ "Font info for number cells containing a total.")
(string-append font-family " Bold 12")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Total label cell") "h" (N_ "Font info for cells containing total labels.")
(string-append font-family " Bold 12")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Centered label cell") "i" (N_ "Font info for centered label cells.")
(string-append font-family " Bold 12")))
)
)
(define (opt-register opt)
(gnc:register-option options opt))
(let ((font-family (gnc-get-default-report-font-family)))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Title") "a" (N_ "Font info for the report title.")
(string-append font-family " Bold 15")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Account link") "b" (N_ "Font info for account name.")
(string-append font-family " Italic 10")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Number cell") "c" (N_ "Font info for regular number cells.")
(string-append font-family " 10")))
(opt-register
(gnc:make-simple-boolean-option
(N_ "Fonts")
(N_ "Negative Values in Red") "d" (N_ "Display negative values in red.")
#t))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Number header") "e" (N_ "Font info for number headers.")
(string-append font-family " 10")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Text cell") "f" (N_ "Font info for regular text cells.")
(string-append font-family " 10")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Total number cell") "g"
(N_ "Font info for number cells containing a total.")
(string-append font-family " Bold 12")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Total label cell") "h"
(N_ "Font info for cells containing total labels.")
(string-append font-family " Bold 12")))
(opt-register
(gnc:make-font-option
(N_ "Fonts")
(N_ "Centered label cell") "i" (N_ "Font info for centered label cells.")
(string-append font-family " Bold 12")))))
;; Adds CSS style information to an html document
(define (add-css-information-to-doc options ssdoc doc)
(let*
((opt-val
(lambda (section name)
(gnc:option-value (gnc:lookup-option options section name))))
(negative-red? (opt-val "Fonts" "Negative Values in Red"))
(alternate-row-color
(gnc:color-option->html
(gnc:lookup-option options
"Colors"
"Alternate Table Cell Color")))
(title-font-info (font-name-to-style-info (opt-val "Fonts" "Title")))
(account-link-font-info (font-name-to-style-info (opt-val "Fonts" "Account link")))
(number-cell-font-info (font-name-to-style-info (opt-val "Fonts" "Number cell")))
(number-header-font-info (font-name-to-style-info (opt-val "Fonts" "Number header")))
(text-cell-font-info (font-name-to-style-info (opt-val "Fonts" "Text 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"))))
(define (opt-font-val name)
(gnc:option-value (gnc:lookup-option options "Fonts" name)))
(define (opt-style-info name) (font-name-to-style-info (opt-font-val name)))
(let* ((negative-red? (opt-font-val "Negative Values in Red"))
(alternate-row-color
(gnc:color-option->html
(gnc:lookup-option options "Colors" "Alternate Table Cell Color")))
(title-info (opt-style-info "Title"))
(account-link-info (opt-style-info "Account link"))
(number-cell-info (opt-style-info "Number cell"))
(number-header-info (opt-style-info "Number header"))
(text-cell-info (opt-style-info "Text cell"))
(total-number-cell-info (opt-style-info "Total number cell"))
(total-label-cell-info (opt-style-info "Total label cell"))
(centered-label-cell-info (opt-style-info "Centered label cell")))
(gnc:html-document-set-style-text!
ssdoc
(string-append
"h3 { " title-font-info " }\n"
"a { " account-link-font-info " }\n"
"body, p, table, tr, td { vertical-align: top; " text-cell-font-info " }\n"
"tr.alternate-row { background: " alternate-row-color " }\n"
"tr { page-break-inside: avoid !important;}\n"
"th.column-heading-left { text-align: left; " number-header-font-info " }\n"
"th.column-heading-center { text-align: center; " number-header-font-info " }\n"
"th.column-heading-right { text-align: right; " number-header-font-info " }\n"
"td.neg { " (if negative-red? "color: red; " "") " }\n"
"td.number-cell, td.total-number-cell { text-align: right; white-space: nowrap; }\n"
"td.date-cell { white-space: nowrap; }\n"
"td.anchor-cell { white-space: nowrap; " text-cell-font-info " }\n"
"td.number-cell { " number-cell-font-info " }\n"
"td.number-header { text-align: right; " number-header-font-info " }\n"
"td.text-cell { " text-cell-font-info " }\n"
"td.total-number-cell { " total-number-cell-font-info " }\n"
"td.total-label-cell { " total-label-cell-font-info " }\n"
"td.centered-label-cell { text-align: center; " centered-label-cell-font-info " }\n"
(or (gnc:html-document-style-text doc) "")
)
)
)
)
(gnc:html-document-set-style-text!
ssdoc
(string-append
"h3 { " title-info " }\n"
"a { " account-link-info " }\n"
"body, p, table, tr, td { vertical-align: top; " text-cell-info " }\n"
"tr.alternate-row { background: " alternate-row-color " }\n"
"tr { page-break-inside: avoid !important;}\n"
"html, body { height: 100vh; margin: 0; }\n"
"td, th { border-color: grey }\n"
"th.column-heading-left { text-align: left; " number-header-info " }\n"
"th.column-heading-center { text-align: center; " number-header-info " }\n"
"th.column-heading-right { text-align: right; " number-header-info " }\n"
"td.neg { " (if negative-red? "color: red; " "") " }\n"
"td.number-cell, td.total-number-cell { text-align: right; white-space: nowrap; }\n"
"td.date-cell { white-space: nowrap; }\n"
"td.anchor-cell { white-space: nowrap; " text-cell-info " }\n"
"td.number-cell { " number-cell-info " }\n"
"td.number-header { text-align: right; " number-header-info " }\n"
"td.text-cell { " text-cell-info " }\n"
"td.total-number-cell { " total-number-cell-info " }\n"
"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
used-columns payable? link-option)
(define (AP-negate num)
(if payable? (- num) num))
(define currency (xaccAccountGetCommodity acc))
(define link-cols (assq-ref '((none . 0) (simple . 1) (detailed . 3)) link-option))
(define (print-totals total debit credit tax sale)
@ -313,8 +315,9 @@
(cons (list (gnc:make-html-table-cell/size 1 2 (_ "Outstanding"))
(make-cell
(gnc:make-gnc-monetary
currency (gnc-lot-get-balance
(gncInvoiceGetPostedLot invoice)))))
currency
(AP-negate (gnc-lot-get-balance
(gncInvoiceGetPostedLot invoice))))))
result))))
(else
(let* ((lot-split (car invoice-splits))
@ -328,7 +331,7 @@
(let* ((tfr-split (car tfr-splits))
(tfr-acct (xaccSplitGetAccount tfr-split))
(tfr-curr (xaccAccountGetCommodity tfr-acct))
(tfr-amt (xaccSplitGetAmount tfr-split)))
(tfr-amt (AP-negate (xaccSplitGetAmount tfr-split))))
(lp1 (cdr tfr-splits)
(cons (list
(qof-print-date (xaccTransGetDate lot-txn))
@ -371,7 +374,7 @@
(let* ((payment-split (car payment-splits))
(inv (car payment-split))
(inv-split (cadr payment-split))
(inv-amount (xaccSplitGetAmount inv-split)))
(inv-amount (AP-negate (xaccSplitGetAmount inv-split))))
(lp (cdr payment-splits)
(- amount inv-amount)
(cons (list

View File

@ -349,6 +349,12 @@
'("-$23.00")
(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
(set! options (default-testing-options))
(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)
(gnc:html-document-title doc))))
(if headline
(if (and headline (not (equal? headline "")))
(gnc:html-document-add-object!
ssdoc
(gnc:make-html-text

View File

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

View File

@ -89,6 +89,8 @@
(define optname-transaction-matcher (N_ "Transaction Filter"))
(define optname-transaction-matcher-regex
(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-void-transactions (N_ "Void 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. ")
#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:make-multichoice-option
pagename-filter optname-reconcile-status
@ -1969,6 +1978,8 @@ be excluded from periodic reporting.")
(lambda () (make-regexp transaction-matcher))
(const 'invalid-transaction-regex))
'no-guile-regex-support)))
(transaction-filter-exclude?
(opt-val pagename-filter optname-transaction-matcher-exclude))
(reconcile-status-filter
(keylist-get-info reconcile-status-list
(opt-val pagename-filter optname-reconcile-status)
@ -2044,6 +2055,11 @@ be excluded from periodic reporting.")
(define (date-comparator? X Y)
(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
((or (null? c_account_1)
(symbol? account-matcher-regexp)
@ -2129,9 +2145,9 @@ be excluded from periodic reporting.")
((include) (is-filter-member split c_account_2))
((exclude) (not (is-filter-member split c_account_2))))
(or (string-null? transaction-matcher)
(match? (xaccTransGetDescription trans))
(match? (xaccTransGetNotes trans))
(match? (xaccSplitGetMemo split)))
(if transaction-filter-exclude?
(not (transaction-filter-match split))
(transaction-filter-match split)))
(or (not custom-split-filter)
(custom-split-filter split)))))
splits))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -178,7 +178,7 @@ employee_guid_handler (xmlNodePtr node, gpointer employee_pdata)
gncEmployeeSetGUID (pdata->employee, guid);
}
g_free (guid);
guid_free (guid);
return TRUE;
}
@ -282,7 +282,7 @@ employee_ccard_handler (xmlNodePtr node, gpointer employee_pdata)
g_return_val_if_fail (guid, FALSE);
ccard_acc = xaccAccountLookup (guid, pdata->book);
g_free (guid);
guid_free (guid);
g_return_val_if_fail (ccard_acc, FALSE);
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);
g_return_val_if_fail (guid, FALSE);
acc = xaccAccountLookup (guid, pdata->book);
g_free (guid);
guid_free (guid);
g_return_val_if_fail (acc, FALSE);
if (func)
@ -314,7 +314,7 @@ set_taxtable (xmlNodePtr node, struct entry_pdata* pdata,
gncTaxTableDecRef (taxtable);
func (pdata->entry, taxtable);
g_free (guid);
guid_free (guid);
return TRUE;
}
@ -339,7 +339,7 @@ entry_guid_handler (xmlNodePtr node, gpointer entry_pdata)
gncEntrySetGUID (pdata->entry, guid);
}
g_free (guid);
guid_free (guid);
return TRUE;
}
@ -579,7 +579,7 @@ entry_order_handler (xmlNodePtr node, gpointer entry_pdata)
gncOrderAddEntry (order, pdata->entry);
gncOrderCommitEdit (order);
g_free (guid);
guid_free (guid);
return TRUE;
}
@ -604,7 +604,7 @@ entry_invoice_handler (xmlNodePtr node, gpointer entry_pdata)
gncInvoiceAddEntry (invoice, pdata->entry);
gncInvoiceCommitEdit (invoice);
g_free (guid);
guid_free (guid);
return TRUE;
}
@ -629,7 +629,7 @@ entry_bill_handler (xmlNodePtr node, gpointer entry_pdata)
gncBillAddEntry (invoice, pdata->entry);
gncInvoiceCommitEdit (invoice);
g_free (guid);
guid_free (guid);
return TRUE;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -182,11 +182,11 @@ owner_id_handler (xmlNodePtr node, gpointer owner_pdata)
}
default:
PWARN ("Invalid owner type: %d\n", gncOwnerGetType (pdata->owner));
g_free (guid);
guid_free (guid);
return FALSE;
}
g_free (guid);
guid_free (guid);
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);
if (!c) return FALSE;
gnc_price_set_guid (p, c);
g_free (c);
guid_free (c);
}
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);
sx_set_template_account (sx, account);
g_free (templ_acct_guid);
guid_free (templ_acct_guid);
return TRUE;
}

View File

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

View File

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

View File

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

View File

@ -251,7 +251,7 @@ test_dom_tree_to_guid (void)
xmlFreeNode (test_node);
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)
{
g_free (cmpid);
guid_free (cmpid);
return TRUE;
}
else
{
g_free (cmpid);
guid_free (cmpid);
return FALSE;
}
}

View File

@ -90,7 +90,7 @@ find_appropriate_node (xmlNodePtr node, Split* spl)
{
account_guid_good = TRUE;
}
g_free (accid);
guid_free (accid);
}
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)))
{
g_free (id);
guid_free (id);
return "ids differ";
}
g_free (id);
guid_free (id);
}
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)))
{
g_free (id);
guid_free (id);
return "accounts differ";
}
g_free (id);
guid_free (id);
}
}
return NULL;

View File

@ -211,14 +211,14 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; flattens an arbitrary deep nested list into simple list. this is
;; 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)
(reverse
(let lp ((e lst) (accum '()))
(if (list? e)
(fold lp accum e)
(cons e accum)))))
(let loop ((lst lst) (acc '()))
(cond
((null? lst) acc)
((pair? lst) (loop (car lst) (loop (cdr lst) acc)))
(else (cons lst acc)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; compatibility hack for fixing guile-2.0 string handling. this code