Merge branch 'sort-filter' of https://github.com/Bob-IT/gnucash into maint

This commit is contained in:
Geert Janssens 2018-08-30 12:18:15 +02:00
commit c977c2350a
6 changed files with 870 additions and 158 deletions

File diff suppressed because it is too large Load Diff

View File

@ -60,13 +60,13 @@
// static QofLogModule log_module = GNC_MOD_SX;
static QofLogModule log_module = GNC_MOD_GUI;
#define STATE_SECTION_REG_PREFIX "Register"
/***** PROTOTYPES ***************************************************/
void gnc_split_reg_raise( GNCSplitReg *gsr );
static GtkWidget* add_summary_label( GtkWidget *summarybar,
const char *label_str );
static GtkWidget* add_summary_label( GtkWidget *summarybar, gboolean pack_start,
const char *label_str, GtkWidget *extra );
static void gsr_summarybar_set_arrow_draw (GNCSplitReg *gsr);
static void gnc_split_reg_determine_read_only( GNCSplitReg *gsr );
@ -347,6 +347,9 @@ gnc_split_reg_init( GNCSplitReg *gsr )
gtk_orientable_set_orientation (GTK_ORIENTABLE(gsr), GTK_ORIENTATION_VERTICAL);
gsr->sort_type = BY_STANDARD;
gsr->sort_rev = FALSE;
gsr->sort_arrow_handler_id = 0;
gsr->filter_text = NULL;
gsr->width = -1;
gsr->height = -1;
gsr->numRows = 10;
@ -443,6 +446,10 @@ gsr_setup_status_widgets( GNCSplitReg *gsr )
void
gnc_split_reg_destroy_cb(GtkWidget *widget, gpointer data)
{
GNCSplitReg *gsr = data;
if (gsr->filter_text)
g_free (gsr->filter_text);
}
/**
@ -531,21 +538,109 @@ gsr_redraw_all_cb (GnucashRegister *g_reg, gpointer data)
print_info = gnc_account_print_info( leader, TRUE );
reverse = gnc_reverse_balance( leader );
gsr_update_summary_label( gsr->balance_label,
xaccAccountGetPresentBalance,
leader, print_info, commodity, reverse, euro );
gsr_update_summary_label( gsr->cleared_label,
xaccAccountGetClearedBalance,
leader, print_info, commodity, reverse, euro );
gsr_update_summary_label( gsr->reconciled_label,
xaccAccountGetReconciledBalance,
leader, print_info, commodity, reverse, euro );
gsr_update_summary_label( gsr->future_label,
xaccAccountGetBalance,
leader, print_info, commodity, reverse, euro );
gsr_update_summary_label( gsr->projectedminimum_label,
xaccAccountGetProjectedMinimumBalance,
leader, print_info, commodity, reverse, euro );
if (gsr->balance_label != NULL) // only test the first as they are a group
{
gsr_update_summary_label( gsr->balance_label,
xaccAccountGetPresentBalance,
leader, print_info, commodity, reverse, euro );
gsr_update_summary_label( gsr->cleared_label,
xaccAccountGetClearedBalance,
leader, print_info, commodity, reverse, euro );
gsr_update_summary_label( gsr->reconciled_label,
xaccAccountGetReconciledBalance,
leader, print_info, commodity, reverse, euro );
gsr_update_summary_label( gsr->future_label,
xaccAccountGetBalance,
leader, print_info, commodity, reverse, euro );
gsr_update_summary_label( gsr->projectedminimum_label,
xaccAccountGetProjectedMinimumBalance,
leader, print_info, commodity, reverse, euro );
}
// Sort label
if (gsr->sort_label != NULL)
{
gchar *old_tt_text = gtk_widget_get_tooltip_text (GTK_WIDGET(gsr->sort_label));
gchar *new_tt_text;
gchar *text = NULL;
switch (gsr->sort_type)
{
case (0):
text = _("None");
break;
case (1):
text = _("Standard Order");
break;
case (2):
text = _("Date");
break;
case (3):
text = _("Date of Entry");
break;
case (4):
text = _("Statement Date");
break;
case (5):
text = _("Number");
break;
case (6):
text = _("Amount");
break;
case (7):
text = _("Memo");
break;
case (8):
text = _("Description");
break;
case (9):
text = _("Action");
break;
case (10):
text = _("Notes");
break;
}
if (gsr->sort_rev)
gtk_widget_set_tooltip_text (GTK_WIDGET(gsr->sort_label), _("Descending"));
else
gtk_widget_set_tooltip_text (GTK_WIDGET(gsr->sort_label), _("Ascending"));
new_tt_text = gtk_widget_get_tooltip_text (GTK_WIDGET(gsr->sort_label));
// does the arrow need changing
if (g_strcmp0 (old_tt_text, new_tt_text) != 0)
gsr_summarybar_set_arrow_draw (gsr);
if (old_tt_text)
g_free (old_tt_text);
if (new_tt_text)
g_free (new_tt_text);
gtk_label_set_text (GTK_LABEL(gsr->sort_label), text);
}
// Filter label
if (gsr->filter_label != NULL)
{
gchar *old_tt_text = gtk_widget_get_tooltip_text (GTK_WIDGET(gsr->filter_label));
// check for a change in text
if (g_strcmp0 (old_tt_text, gsr->filter_text) != 0)
{
if (gsr->filter_text != NULL)
gtk_label_set_text (GTK_LABEL(gsr->filter_label), _("Filtered"));
else
gtk_label_set_text (GTK_LABEL(gsr->filter_label), "");
gtk_widget_set_tooltip_text (GTK_WIDGET(gsr->filter_label), gsr->filter_text);
if (old_tt_text)
g_free (old_tt_text);
}
}
if (gsr->shares_label == NULL && gsr->value_label == NULL)
return;
amount = xaccAccountGetBalance( leader );
@ -1866,16 +1961,18 @@ gnc_split_reg_sort_notes_cb(GtkWidget *w, gpointer data)
void
gnc_split_reg_set_sort_reversed(GNCSplitReg *gsr, gboolean rev)
gnc_split_reg_set_sort_reversed(GNCSplitReg *gsr, gboolean rev, gboolean refresh)
{
/* Note: sort_reversed is the boolean opposite of sort_increasing
* so when rev == true, we're sorting decreasing
* In other words, qof_query_set_sort_increasing should
* always use the inverse of rev.
*/
Query *query = gnc_ledger_display_get_query( gsr->ledger );
qof_query_set_sort_increasing (query, !rev, !rev, !rev);
gnc_ledger_display_refresh( gsr->ledger );
/* Note: sort_reversed is the boolean opposite of sort_increasing
* so when rev == true, we're sorting decreasing
* In other words, qof_query_set_sort_increasing should
* always use the inverse of rev.
*/
Query *query = gnc_ledger_display_get_query( gsr->ledger );
qof_query_set_sort_increasing (query, !rev, !rev, !rev);
gsr->sort_rev = rev;
if (refresh)
gnc_ledger_display_refresh( gsr->ledger );
}
static void
@ -2003,14 +2100,17 @@ gnc_split_reg_size_allocate (GtkWidget *widget,
static
GtkWidget*
add_summary_label (GtkWidget *summarybar, const char *label_str)
add_summary_label (GtkWidget *summarybar, gboolean pack_start, const char *label_str, GtkWidget *extra)
{
GtkWidget *hbox;
GtkWidget *label;
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
gtk_box_pack_start( GTK_BOX(summarybar), hbox, FALSE, FALSE, 5 );
if (pack_start)
gtk_box_pack_start( GTK_BOX(summarybar), hbox, FALSE, FALSE, 5 );
else
gtk_box_pack_end( GTK_BOX(summarybar), hbox, FALSE, FALSE, 5 );
label = gtk_label_new( label_str );
gnc_label_set_alignment(label, 1.0, 0.5 );
@ -2020,44 +2120,65 @@ add_summary_label (GtkWidget *summarybar, const char *label_str)
gnc_label_set_alignment(label, 1.0, 0.5 );
gtk_box_pack_start( GTK_BOX(hbox), label, FALSE, FALSE, 0 );
if (extra != NULL)
gtk_box_pack_start( GTK_BOX(hbox), extra, FALSE, FALSE, 0 );
return label;
}
static void
gsr_summarybar_set_arrow_draw (GNCSplitReg *gsr)
{
if (gsr->sort_arrow_handler_id > 0)
g_signal_handler_disconnect (G_OBJECT(gsr->sort_arrow), gsr->sort_arrow_handler_id);
gsr->sort_arrow_handler_id = g_signal_connect (G_OBJECT (gsr->sort_arrow), "draw",
G_CALLBACK (gnc_draw_arrow_cb), GINT_TO_POINTER(gsr->sort_rev));
gtk_widget_queue_draw (gsr->sort_arrow);
}
GtkWidget *
gsr_create_summary_bar( GNCSplitReg *gsr )
{
GtkWidget *summarybar;
GtkWidget *summarybar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_set_homogeneous (GTK_BOX (summarybar), FALSE);
gtk_widget_set_name (summarybar, "gnc-id-summarybar");
gsr->cleared_label = NULL;
gsr->balance_label = NULL;
gsr->reconciled_label = NULL;
gsr->future_label = NULL;
gsr->projectedminimum_label = NULL;
gsr->sort_label = NULL;
gsr->sort_arrow = NULL;
gsr->filter_label = NULL;
gsr->shares_label = NULL;
gsr->value_label = NULL;
if ( gnc_ledger_display_type(gsr->ledger) >= LD_SUBACCOUNT )
if (gnc_ledger_display_type(gsr->ledger) == LD_SINGLE)
{
gsr->summarybar = NULL;
return NULL;
if (!xaccAccountIsPriced(gnc_ledger_display_leader(gsr->ledger)))
{
gsr->balance_label = add_summary_label (summarybar, TRUE, _("Present:"), NULL);
gsr->future_label = add_summary_label (summarybar, TRUE, _("Future:"), NULL);
gsr->cleared_label = add_summary_label (summarybar, TRUE, _("Cleared:"), NULL);
gsr->reconciled_label = add_summary_label (summarybar, TRUE, _("Reconciled:"), NULL);
gsr->projectedminimum_label = add_summary_label (summarybar, TRUE, _("Projected Minimum:"), NULL);
}
else
{
gsr->shares_label = add_summary_label (summarybar, TRUE, _("Shares:"), NULL);
gsr->value_label = add_summary_label (summarybar, TRUE, _("Current Value:"), NULL);
}
}
summarybar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_set_homogeneous (GTK_BOX (summarybar), FALSE);
gsr->filter_label = add_summary_label (summarybar, FALSE, "", NULL);
gsr->sort_arrow = gtk_image_new_from_icon_name ("image-missing", GTK_ICON_SIZE_SMALL_TOOLBAR);
gsr->sort_label = add_summary_label (summarybar, FALSE, _("Sort By: "), gsr->sort_arrow);
if (!xaccAccountIsPriced(gnc_ledger_display_leader(gsr->ledger)))
{
gsr->balance_label = add_summary_label (summarybar, _("Present:"));
gsr->future_label = add_summary_label (summarybar, _("Future:"));
gsr->cleared_label = add_summary_label (summarybar, _("Cleared:"));
gsr->reconciled_label = add_summary_label (summarybar, _("Reconciled:"));
gsr->projectedminimum_label = add_summary_label (summarybar, _("Projected Minimum:"));
}
else
{
gsr->shares_label = add_summary_label (summarybar, _("Shares:"));
gsr->value_label = add_summary_label (summarybar, _("Current Value:"));
}
gnc_widget_set_style_context (GTK_WIDGET(gsr->filter_label), "gnc-class-highlight");
gnc_widget_set_style_context (GTK_WIDGET(gsr->sort_arrow), "gnc-class-highlight");
gsr->summarybar = summarybar;

View File

@ -36,6 +36,8 @@
#define GNC_SPLIT_REG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST( klass, gnc_split_reg_get_type(), GNCSplitRegClass )
#define IS_GNC_SPLIT_REG(obj) G_TYPE_CHECK_INSTANCE_TYPE( obj, gnc_split_reg_get_type() )
#define STATE_SECTION_REG_PREFIX "Register"
typedef struct _GNCSplitReg GNCSplitReg;
typedef struct _GNCSplitRegClass GNCSplitRegClass;
@ -74,6 +76,9 @@ struct _GNCSplitReg
GtkWidget *projectedminimum_label;
GtkWidget *shares_label;
GtkWidget *value_label;
GtkWidget *sort_label;
GtkWidget *sort_arrow;
GtkWidget *filter_label;
/** The current ledger display. **/
GNCLedgerDisplay *ledger;
@ -82,7 +87,10 @@ struct _GNCSplitReg
gint numRows;
guint sort_type;
guint sort_type;
gboolean sort_rev;
gulong sort_arrow_handler_id;
gchar *filter_text;
gboolean read_only;
};
@ -197,8 +205,8 @@ void gnc_split_reg_set_sort_type_force( GNCSplitReg *gsr, SortType t, gboolean f
/**
* Set/get sort order of register
**/
void gnc_split_reg_set_sort_reversed(GNCSplitReg *gsr, gboolean rev);
**/
void gnc_split_reg_set_sort_reversed(GNCSplitReg *gsr, gboolean rev, gboolean refresh);
/**

View File

@ -1,7 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.20.4 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkAdjustment" id="days_adjustment">
<property name="upper">1100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkDialog" id="filter_by_dialog">
<property name="can_focus">False</property>
<property name="border_width">6</property>
@ -87,19 +92,53 @@
</packing>
</child>
<child>
<object class="GtkLabel" id="label847680">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkRadioButton" id="filter_show_days">
<property name="label" translatable="yes">Show _number of days</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">filter_show_all</property>
<signal name="toggled" handler="gnc_plugin_page_register_filter_select_range_cb" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="filter_show_num_days">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Valid range is 0 to 1100 days
If 0, all previous days included</property>
<property name="adjustment">days_adjustment</property>
<property name="numeric">True</property>
<signal name="value-changed" handler="gnc_plugin_page_register_filter_days_changed_cb" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="filter_show_range">
<property name="label" translatable="yes">Select Range:</property>
<property name="label" translatable="yes">Select _Range:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -123,6 +162,7 @@
<child>
<object class="GtkLabel" id="label847682">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes" comments="Filter By Dialog, Date Tab, Start section">Start:</property>
</object>
<packing>
@ -209,6 +249,7 @@
<child>
<object class="GtkLabel" id="label847684">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes" comments="Filter By Dialog, Date Tab, End section">End:</property>
</object>
<packing>
@ -510,6 +551,9 @@
<action-widget response="-6">cancelbutton4</action-widget>
<action-widget response="-5">okbutton4</action-widget>
</action-widgets>
<child>
<placeholder/>
</child>
</object>
<object class="GtkAdjustment" id="num_adjustment">
<property name="upper">1000000000</property>
@ -864,6 +908,9 @@
<action-widget response="-6">cancelbutton2</action-widget>
<action-widget response="-5">okbutton2</action-widget>
</action-widgets>
<child>
<placeholder/>
</child>
</object>
<object class="GtkAdjustment" id="tnum_adjustment">
<property name="upper">1000000000</property>
@ -1053,6 +1100,9 @@
<action-widget response="-6">button76</action-widget>
<action-widget response="-5">button77</action-widget>
</action-widgets>
<child>
<placeholder/>
</child>
</object>
<object class="GtkDialog" id="void_transaction_dialog">
<property name="can_focus">False</property>
@ -1158,5 +1208,8 @@
<action-widget response="-6">cancelbutton1</action-widget>
<action-widget response="-5">okbutton1</action-widget>
</action-widgets>
<child>
<placeholder/>
</child>
</object>
</interface>

View File

@ -48,6 +48,7 @@ static gncFeature known_features[] =
{ GNC_FEATURE_GUID_BAYESIAN, "Use account GUID as key for Bayesian data (requires at least GnuCash 2.6.12)" },
{ GNC_FEATURE_GUID_FLAT_BAYESIAN, "Use account GUID as key for bayesian data and store KVP flat (requires at least Gnucash 2.6.19)" },
{ GNC_FEATURE_SQLITE3_ISO_DATES, "Use ISO formatted date-time strings in SQLite3 databases (requires at least GnuCash 2.6.20)"},
{ GNC_FEATURE_REG_SORT_FILTER, "Store the register sort and filter settings in .gcm metadata file (requires at least GnuCash 3.3)"},
{ NULL },
};
@ -72,7 +73,7 @@ static void gnc_features_init ()
}
static void gnc_features_test_one(gpointer pkey, gpointer value,
gpointer data)
gpointer data)
{
const gchar *key = (const gchar*)pkey;
const gchar *feature_desc = (const gchar*)value;
@ -89,7 +90,7 @@ static void gnc_features_test_one(gpointer pkey, gpointer value,
g_assert(feature_desc);
*unknown_features = g_list_prepend(*unknown_features,
(gpointer)feature_desc);
(gpointer)feature_desc);
}
/* Check if the session requires features unknown to this version of GnuCash.
@ -108,25 +109,25 @@ gchar *gnc_features_test_unknown (QofBook *book)
/* Iterate over the members of this frame for unknown features */
g_hash_table_foreach (features_used, &gnc_features_test_one,
&features_list);
&features_list);
if (features_list)
{
GList *i;
char* msg = g_strdup(_("This Dataset contains features not supported "
"by this version of GnuCash. You must use a "
"newer version of GnuCash in order to support "
"the following features:"
));
GList *i;
char* msg = g_strdup(_("This Dataset contains features not supported "
"by this version of GnuCash. You must use a "
"newer version of GnuCash in order to support "
"the following features:"
));
for (i = features_list; i; i = i->next)
{
char *tmp = g_strconcat(msg, "\n* ", i->data, NULL);
g_free (msg);
msg = tmp;
}
for (i = features_list; i; i = i->next)
{
char *tmp = g_strconcat(msg, "\n* ", i->data, NULL);
g_free (msg);
msg = tmp;
}
g_list_free(features_list);
return msg;
g_list_free(features_list);
return msg;
}
g_hash_table_unref (features_used);
return NULL;
@ -159,7 +160,7 @@ struct CheckFeature
};
static void gnc_features_check_feature_cb (gpointer pkey, gpointer value,
gpointer data)
gpointer data)
{
const gchar *key = (const gchar*)pkey;
struct CheckFeature * check_data = data;

View File

@ -52,6 +52,7 @@ extern "C" {
#define GNC_FEATURE_GUID_BAYESIAN "Account GUID based Bayesian data"
#define GNC_FEATURE_GUID_FLAT_BAYESIAN "Account GUID based bayesian with flat KVP"
#define GNC_FEATURE_SQLITE3_ISO_DATES "ISO-8601 formatted date strings in SQLite3 databases."
#define GNC_FEATURE_REG_SORT_FILTER "Register sort and filter settings stored in .gcm file"
/** @} */