r20294 - gnucash/trunk/src/business - Implement command for changing the ordering of invoice entries by moving them up or down one row.

Christian Stimming cstim at code.gnucash.org
Sat Feb 12 16:55:57 EST 2011


Author: cstim
Date: 2011-02-12 16:55:57 -0500 (Sat, 12 Feb 2011)
New Revision: 20294
Trac: http://svn.gnucash.org/trac/changeset/20294

Modified:
   gnucash/trunk/src/business/business-gnome/dialog-invoice.c
   gnucash/trunk/src/business/business-gnome/dialog-invoice.h
   gnucash/trunk/src/business/business-gnome/gnc-plugin-page-invoice.c
   gnucash/trunk/src/business/business-gnome/ui/gnc-plugin-page-invoice-ui.xml
   gnucash/trunk/src/business/business-ledger/gncEntryLedger.c
   gnucash/trunk/src/business/business-ledger/gncEntryLedger.h
Log:
Implement command for changing the ordering of invoice entries by moving them up or down one row.

Turned out this is rather easy: Just swap the "date-entered" of both items.

Modified: gnucash/trunk/src/business/business-gnome/dialog-invoice.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-invoice.c	2011-02-12 21:55:46 UTC (rev 20293)
+++ gnucash/trunk/src/business/business-gnome/dialog-invoice.c	2011-02-12 21:55:57 UTC (rev 20294)
@@ -474,6 +474,23 @@
         gnc_ui_invoice_duplicate (invoice);
 }
 
+void gnc_invoice_window_entryUpCB (GtkWidget *widget, gpointer data)
+{
+    InvoiceWindow *iw = data;
+    if (!iw || !iw->ledger)
+        return;
+
+    gnc_entry_ledger_move_current_entry_updown(iw->ledger, TRUE);
+}
+void gnc_invoice_window_entryDownCB (GtkWidget *widget, gpointer data)
+{
+    InvoiceWindow *iw = data;
+    if (!iw || !iw->ledger)
+        return;
+
+    gnc_entry_ledger_move_current_entry_updown(iw->ledger, FALSE);
+}
+
 void
 gnc_invoice_window_recordCB (GtkWidget *widget, gpointer data)
 {

Modified: gnucash/trunk/src/business/business-gnome/dialog-invoice.h
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-invoice.h	2011-02-12 21:55:46 UTC (rev 20293)
+++ gnucash/trunk/src/business/business-gnome/dialog-invoice.h	2011-02-12 21:55:57 UTC (rev 20294)
@@ -112,4 +112,7 @@
 void gnc_invoice_window_payment_cb (GtkWidget *widget, gpointer data);
 void gnc_invoice_window_report_owner_cb (GtkWidget *widget, gpointer data);
 
+void gnc_invoice_window_entryUpCB (GtkWidget *widget, gpointer data);
+void gnc_invoice_window_entryDownCB (GtkWidget *widget, gpointer data);
+
 #endif /* GNC_DIALOG_INVOICE_H_ */

Modified: gnucash/trunk/src/business/business-gnome/gnc-plugin-page-invoice.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/gnc-plugin-page-invoice.c	2011-02-12 21:55:46 UTC (rev 20293)
+++ gnucash/trunk/src/business/business-gnome/gnc-plugin-page-invoice.c	2011-02-12 21:55:57 UTC (rev 20294)
@@ -86,6 +86,9 @@
 static void gnc_plugin_page_redraw_help_cb( GnucashRegister *gsr, GncPluginPageInvoice *invoice_page );
 static void gnc_plugin_page_invoice_refresh_cb (GHashTable *changes, gpointer user_data);
 
+static void gnc_plugin_page_invoice_cmd_entryUp (GtkAction *action, GncPluginPageInvoice *plugin_page);
+static void gnc_plugin_page_invoice_cmd_entryDown (GtkAction *action, GncPluginPageInvoice *plugin_page);
+
 /************************************************************
  *                          Actions                         *
  ************************************************************/
@@ -171,6 +174,16 @@
         N_("Make a copy of the current entry"),
         G_CALLBACK (gnc_plugin_page_invoice_cmd_duplicateEntry)
     },
+    {
+        "EntryUpAction", GTK_STOCK_GO_UP, N_("Move Entry _Up"), NULL,
+        N_("Move the current entry one row upwards"),
+        G_CALLBACK (gnc_plugin_page_invoice_cmd_entryUp)
+    },
+    {
+        "EntryDownAction", GTK_STOCK_GO_DOWN, N_("Move Entry Do_wn"), NULL,
+        N_("Move the current entry one row downwards"),
+        G_CALLBACK (gnc_plugin_page_invoice_cmd_entryDown)
+    },
 
     /* Business menu */
     {
@@ -220,6 +233,8 @@
     "CancelEntryAction",
     "DeleteEntryAction",
     "DuplicateEntryAction",
+    "EntryUpAction",
+    "EntryDownAction",
     "BlankEntryAction",
     NULL
 };
@@ -237,6 +252,8 @@
     { "CancelEntryAction", 	  N_("Cancel") },
     { "DeleteEntryAction", 	  N_("Delete") },
     { "DuplicateEntryAction",       N_("Duplicate") },
+    { "EntryUpAction", N_("Up") },
+    { "EntryDownAction", N_("Down") },
     { "BlankEntryAction",           N_("Blank") },
     { "EditPostInvoiceAction",      N_("Post") },
     { "EditUnpostInvoiceAction",    N_("Unpost") },
@@ -841,6 +858,32 @@
 }
 
 static void
+gnc_plugin_page_invoice_cmd_entryUp (GtkAction *action,
+                                     GncPluginPageInvoice *plugin_page)
+{
+    GncPluginPageInvoicePrivate *priv;
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+    priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
+    gnc_invoice_window_entryUpCB(NULL, priv->iw);
+    LEAVE(" ");
+}
+
+static void
+gnc_plugin_page_invoice_cmd_entryDown (GtkAction *action,
+                                       GncPluginPageInvoice *plugin_page)
+{
+    GncPluginPageInvoicePrivate *priv;
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_INVOICE(plugin_page));
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+    priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(plugin_page);
+    gnc_invoice_window_entryDownCB(NULL, priv->iw);
+    LEAVE(" ");
+}
+
+static void
 gnc_plugin_page_invoice_cmd_pay_invoice (GtkAction *action,
         GncPluginPageInvoice *plugin_page)
 {

Modified: gnucash/trunk/src/business/business-gnome/ui/gnc-plugin-page-invoice-ui.xml
===================================================================
--- gnucash/trunk/src/business/business-gnome/ui/gnc-plugin-page-invoice-ui.xml	2011-02-12 21:55:46 UTC (rev 20293)
+++ gnucash/trunk/src/business/business-gnome/ui/gnc-plugin-page-invoice-ui.xml	2011-02-12 21:55:57 UTC (rev 20294)
@@ -31,6 +31,8 @@
         <menuitem name="BlankEntry"        	action="BlankEntryAction"/>
         <separator name="ActionsSep4"/>
         <menuitem name="DuplicateEntry"    	action="DuplicateEntryAction"/>
+        <menuitem name="UpEntry"    	action="EntryUpAction"/>
+        <menuitem name="DownEntry"    	action="EntryDownAction"/>
       </placeholder>
     </menu>
 
@@ -62,6 +64,8 @@
       <toolitem name="ToolbarCancelEntry"    	action="CancelEntryAction"/>
       <toolitem name="ToolbarDeleteEntry"    	action="DeleteEntryAction"/>
       <toolitem name="ToolbarDuplicateEntry" 	action="DuplicateEntryAction"/>
+        <toolitem name="ToolbarUpEntry"    	action="EntryUpAction"/>
+        <toolitem name="ToolbarDownEntry"    	action="EntryDownAction"/>
       <toolitem name="ToolbarBlankEntry"     	action="BlankEntryAction"/>
       <separator name="ToolbarSep68"/>
       <toolitem name="ToolbarPostInvoice"       action="EditPostInvoiceAction"/>
@@ -77,6 +81,8 @@
       <menuitem name="DeleteEntry"       		action="DeleteEntryAction"/>
       <separator name="PopupSep1"/>
       <menuitem name="DuplicateEntry"    		action="DuplicateEntryAction"/>
+      <menuitem name="UpEntry"    	action="EntryUpAction"/>
+      <menuitem name="DownEntry"  	action="EntryDownAction"/>
       <menuitem name="BlankEntry"        		action="BlankEntryAction"/>
     </placeholder>
   </popup>

Modified: gnucash/trunk/src/business/business-ledger/gncEntryLedger.c
===================================================================
--- gnucash/trunk/src/business/business-ledger/gncEntryLedger.c	2011-02-12 21:55:46 UTC (rev 20293)
+++ gnucash/trunk/src/business/business-ledger/gncEntryLedger.c	2011-02-12 21:55:57 UTC (rev 20294)
@@ -874,6 +874,10 @@
         gncEntryCopy (entry, new_entry);
         gncEntrySetDate (new_entry, ledger->last_date_entered);
 
+        /* We also must set a new DateEntered on the new entry
+         * because otherwise the ordering is not deterministic */
+        gncEntrySetDateEntered (new_entry, timespec_now());
+
         /* Set the hint for where to display on the refresh */
         ledger->hint_entry = new_entry;
     }
@@ -899,3 +903,75 @@
 
     ledger->gconf_section = string;
 }
+
+void gnc_entry_ledger_move_current_entry_updown (GncEntryLedger *ledger,
+        gboolean move_up)
+{
+    GncEntry *blank, *current, *target;
+    VirtualCellLocation vcell_loc;
+
+    g_assert(ledger);
+
+    blank = gnc_entry_ledger_get_blank_entry(ledger);
+    if (!blank)
+        return;
+
+    /* Ensure we have a valid current GncEntry and it isn't the blank
+     * entry */
+    current = gnc_entry_ledger_get_current_entry(ledger);
+    if (!current || current == blank)
+        return;
+
+    /* Obtain the GncEntry at the up or down virtual table location */
+    vcell_loc = ledger->table->current_cursor_loc.vcell_loc;
+    if (move_up)
+    {
+        if (vcell_loc.virt_row == 0)
+            return;
+        vcell_loc.virt_row--;
+    }
+    else
+    {
+        vcell_loc.virt_row++;
+    }
+
+    /* Ensure we have a valid other GncEntry and it isn't the blank
+     * entry */
+    target = gnc_entry_ledger_get_entry(ledger, vcell_loc);
+    if (!target || target == blank)
+        return;
+
+    /*g_warning("Ok, current desc='%s' target desc='%s'",
+              gncEntryGetDescription(current),
+              gncEntryGetDescription(target));*/
+
+    gnc_suspend_gui_refresh ();
+
+    /* Swap the date-entered of both entries. That's already
+     * sufficient! */
+    {
+        Timespec time_current = gncEntryGetDateEntered(current);
+        Timespec time_target = gncEntryGetDateEntered(target);
+
+        /* Special treatment for identical times (potentially caused
+         * by the "duplicate entry" command) */
+        if (timespec_equal(&time_current, &time_target))
+        {
+            /*g_warning("Surprise - both DateEntered are equal.");*/
+            /* We just increment the DateEntered of the previously
+             * lower of the two by one second. This might still cause
+             * issues if multiple entries had this problem, but
+             * whatever. */
+            if (move_up)
+                time_current.tv_sec++;
+            else
+                time_target.tv_sec++;
+        }
+
+        /* Write the new DateEntered. */
+        gncEntrySetDateEntered(current, time_target);
+        gncEntrySetDateEntered(target, time_current);
+    }
+
+    gnc_resume_gui_refresh ();
+}

Modified: gnucash/trunk/src/business/business-ledger/gncEntryLedger.h
===================================================================
--- gnucash/trunk/src/business/business-ledger/gncEntryLedger.h	2011-02-12 21:55:46 UTC (rev 20293)
+++ gnucash/trunk/src/business/business-ledger/gncEntryLedger.h	2011-02-12 21:55:57 UTC (rev 20294)
@@ -138,6 +138,16 @@
 void gnc_entry_ledger_delete_current_entry (GncEntryLedger *ledger);
 void gnc_entry_ledger_duplicate_current_entry (GncEntryLedger *ledger);
 
+/** This implements the command of moving the current entry (where the
+ * cursor is currently located) one row upwards or downwards,
+ * effectively swapping this row and the other row. If the other row
+ * is empty (or it is the blank entry), nothing will happen.
+ *
+ * \param move_up If TRUE, the current entry is moved upwards,
+ * otherwise downwards. */
+void gnc_entry_ledger_move_current_entry_updown (GncEntryLedger *ledger,
+        gboolean move_up);
+
 QofQuery * gnc_entry_ledger_get_query (GncEntryLedger *ledger);
 
 void gnc_entry_ledger_set_gconf_section (GncEntryLedger *ledger, const gchar *string);



More information about the gnucash-changes mailing list