RFC: refactoring window-register as widget-register + containing window

Derek Atkins warlord@MIT.EDU
22 Nov 2001 20:09:06 -0500


The business accounting package will want to use this, too..  In
particular, to create and edit Orders and Invoices.  However I
might need a few more signals than you provide.  For example
when viewing the A/R account, it would be nice if there were a
way not only to bring up an account but to pop-up the Invoice
associated with a transaction.  Or, perhaps, to bring up the
Customer.

I was planning to use the register, and a generic version would
be really nice.  How flexible can we make it?

Great start!

-derek

Josh Sled <jsled@asynchronous.org> writes:

> I'm attempting to fix something that came up earlier in the course
> of Scheduled Transaction UI development... where I needed to
> cut-and-paste a bunch of code from src/gnome/window-register.c into
> dialog-scheduledxaction.c to get a register in the SX Editor.  I decided
> at the time that that was a to-be-short-term-lived hack to see if/how
> it all worked, and that something like this would be necessary, later.
> Now, as the SX since-last-run dialog wants two more "embedded" registers,
> it seems like time to do it.
> 
> As this is a fairly major change, I'd like input before proceeding
> much further [i.e., actually making the changes], and definitely before
> committing back.
> 
> ...jsled
> 
> 
> RFC:
> Refactoring window-register into a composite widget and containing window.
> 
> Overview
> --------
> 
> The Scheduled Transaction functionality desires to have multiple instances of
> the register available for its UI [SX editing of template transactions and
> review of created transactions in the since-last-run Druid].  For end-user
> convenience, these instances should look-n-feel as close to the
> window-register [src/gnome/window-register.c] as is possible.
> 
> More specifically, there are four generically-useful bits in
> window-register.c:
> 
> . the ledger_display itself
> . the toolbar
> . the popup menu
> . the status bar
> 
> These UI elts are configured in static functions in window-register.c, and
> their callbacks are also static, leading to cut-and-paste for anyone else who
> wants to use the register + toolbar + popup + statusbar... and even more
> cut-n-paste to get the same behavior from the various toolbar buttons and
> popup-menu-items.
> 
> Proposal
> --------
> 
> I propose that these UI elts be brought out in a register composite widget
> [widget-register].  This widget would be a vbox which would contain the four
> widgets: toolbar, ledger_display, status bar and popup menu.
> 
> [ I now utilize a distinction between the "window-register" [the existing
>   register in src/gnome/window-register.c] and "widget-register" [the
>   to-be-created register composite widget. ]
> 
> Each of the widget-register's contained UI sub-elts is exposed to the caller
> for modification; for instance, the window-register itself adds the following
> toolbar actions:
> 
> . close
> 
> . transfer
> . find
> . report
> . print
> 
> The popup menu, as well, will perhaps want to be modified by the caller; in
> the SX Editor, there is no menubar on the dialog... thus there is no menu bar
> for the actions which are currently in the window-register's Register, Edit
> and Transaction menus.  A subset of the menu options provided by the
> window-register [such as modifying the display style, exposing cut/paste
> functionality] should be provided by the context/popup menu, or perhaps in
> the toolbar... but in any case, the caller will want to modify the existing
> menus where necessary to provide all appropriate functionality.
> 
> 
> This code would live in src/gnome-util/gnc-regwidget.[ch], with functions
> prefixed with "gnc_regwidget_".
> 
> Supported
> ---------
> 
> Looking at the window-register, there is a bunch of functionality present;
> looking at my initial cut-n-paste of [a subset of] the window-register.c code
> into the SX Editor, only some of this functionality was transfered over.
> Specifically, the widget-register should support:
> 
> . Creation, by passing in the display_ledger to use, already configured
>   for/with the appropriate type/Query.
> 
> [ These are the common actions between the toolbar and popup menu... more
>   importantly, they seem "common" to both uses of the register. ]
> . Enter
> . Cancel
> . Delete
> . Duplicate
> . Schedule
> . Split
> . Blank
> . Jump
> . Transfer
> 
> . Style options
>   . Basic, Auto, Journal
>   . Double-line
> 
> . Copy [split | txn]
> . Cut [split | txn]
> . Paste [split | txn]
> 
> Unsupported
> -----------
> 
> The following functionality will be supported by the caller, if necessary
> [read: the window-register will support these, as the SX-based callers won't
> use it]
> 
> . Sorting
> . Date-range selection
> . Account editing/creation
> . Check/repair
> . Find
> . Report
> . Print
> . Invoice
> . Stock splitting
> . Reconciliation
> 
> Functionality Vector
> --------------------
> 
> A goal of this effort is consistency: the user has experience with the
> window-register, and has created a mental map of actions and effects [and if
> they haven't, it will retard that map creation by having multiple different
> registers in different parts of the program].  Thus, the set of functionality
> that the widget-register supports should be configurable in such a way that
> not-available items ["Schedule..." while editing a Scheduled Transaction's
> template-transaction] are not removed, but only grayed out.
> 
> This shall be done with a bitmask to be passed into the widget-register,
> specifying which functionality to turn off.  Functionality which is turned
> off is left visually in place, but set to be insensitive, and thus the
> callbacks are not able to be invoked.  Probably the right thing, then, to do
> is not attach the callbacks at all.
> 
> Handling Actions
> ----------------
> 
> Presently, the window-register directly attaches callbacks for the
> clicked/activated signals of the widgets it creates.  However, this is
> problematic in the widget-register case as the widget-register will create
> the widgets, and the caller will want to attach the signals.
> 
> One option is to provide accessors for all of the sub-widgets to the caller,
> but this assumes that all callers have a bit too much knowledge about how the
> widget-register is working.
> 
> Thus, the widget-register will emit the following signals on sub-widget
> activation, and the widget-register itself can be the object-of-attachment
> for all the caller's event-handling purposes:
> 
> . "enter_txn"
> . "cancel_txn"
> . "delete_txn" [?]
> . "duplicate_txn"
> . "schedule_txn"
> . "show_split_req"
> . "jump_to_blank"
> . "jump_to_acct"
> . "transfer"
> 
> . "cut_split", "cut_txn"
> . "copy_split", "copy_txn"
> . "paste_split", "paste_txn"
> 
> . "style_change"
> 
> These signals will be attached-to by default handlers [provided by the
> widget-register]... however, these default signal-handlers will be set to be
> handled last, iff any later-attached signal handlers allow them to run [via
> return status].
> 
> This will entail certain changes in how the caller[s] function.  Presently,
> for instance, the window-register attaches the same callback [recordCB] to
> both the "Enter" option in the popup menu and the 'Transaction | Enter'
> window-menu item.  This, in turn, calls gnc_register_enter, which does some
> register manip.
> 
> Now, with widget-register, the window-register could still create a
> 'Transaction | Enter' menu item, but the callback would instead force the
> widget-register to emit the "enter_txn" signal, which would trigger the same
> code, now provided by the widget-register.  If the window-register had added
> another callback, it would be invoked first, perhaps blocking the invocation
> of the "standard" "enter_txn" signal-handler.
> 
> Unknown/Questions
> -----------------
> 
> . Gnome Dock stuff
> 
>   . The window-register makes use of the GnomeDock for the menu, toolbar and
>   summarybar... I guess this can be the case for the widget-register as well,
>   but it doesn't seem quite right; the caller probably wants to retain
>   control about how all that is used.
> 
> . Functionality Vector
> 
>   . This seems to me like the right thing; we don't want the "Schedule"
>   option to be available in the SX editor, but we don't want it to just
>   disappear... is there a better way of spec'ing what features
>   should/shouldn't be supported by the resulting widget-register?
> 
>   . Another option would be to ignore the functionality vector, create a
>   widget-register, then go through and set_sensitive( FALSE ) the appropriate
>   widgets.
> 
> . Signal/handler policy a good idea?
> 
>   . I'm not sure this _quite_ works.  The intent is to minimize the work that
>   the callers have to [re-]do in order to get the "standard" register into
>   their UI.  However, let's take the case of the "Duplicate" button.  In the
>   SX Editor, clicking the duplicate button seems to work, except both the
>   Date and Num that it asks for from the user are irrelevant to
>   template-transaction editing.  After that, only the split memos are
>   duplicated, as the accounts and credit/debit formulas are in
>   kvp-frames... so this seems like something that would need to be re-written
>   anyways...  OTOH, enter, cancel, blank [presumably cut, copy, paste], work
>   fine with no re-writing.
> 
> . Menus/Toolbars
> 
>   . There's a pretty compelling argument which says that the different menus
>   [both the containing-window menus and the popup menu] should be as common
>   as possible, both in display and code/data-structures... do we want to have
>   some way assisting in this?  Perhaps the caller can ask the widget-register
>   for a menu, which is can then modify and place in it's own menubar?
> 
> . Vbox usage [Present/Future/Cleared/Reconciled bar] cleanliness
> 
>   . The window-register will want to add other UI elts [such as the
>   Preset/Future/Cleared/Reconciled label bar] ... is there a cleaner way
>   of doing this than gtk_box-inserting the new widgets at the right places?
> 
> . Status bar
> 
>   . The caller may want to re-place the summarybar at a different location,
>   but the widget-register still needs to update it; this shouldn't be a
>   problem.
> 
>   . If the caller wants a different interface than the status bar, that's
>   more problematic...
> 
> Looks Like...
> -------------
> 
> A quick example:
> 
> GNCLedgerDisplay *gnc_regwidget_get_ledger_display( GNCRegWidget* );
> /* should these be gncUIWidget*s? */
> GtkWidget *gnc_regwidget_get_toolbar( GNCRegWidget* );
> GtkWidget *gnc_regwidget_get_statusbar( GNCRegWidget* );
> GtkWidget *gnc_regwidget_get_popup_menu( GNCRegWidget* );
> 
> /* [maybe, as per "Menus/Toolbars" comment above.]
>  * If m is non-null, appends elts ["enter", "cancel", "delete", <divider>,
>  * "duplicate"...] otherwise, creates a new GtkMenu.
>  *  Returns either m or the new GtkMenu.
>  */
> GtkWidget *gnc_regwidget_get_menu( GNCRegWidget*, GtkWidget *m );
> 
> /***** signal-handler prototypes *****/
> 
> gboolean (*enter_txn_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*cancel_txn_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*delete_tnx_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*dup_txn_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*sched_txn_cb_fn)( GNCRegWidget*, gpointer user_data );
> /* "show_split_req" signal
>  * Though thinking about it, this will either be on or off [depending on how
>  * authoritarian the caller is being about display-control, and it should
>  * never need to be over-ridden. */
> gboolean (*show_split_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*jump_to_blank_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*jump_to_acct_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*transfer_cb_fn)( GNCRegWidget*, gpointer user_data );
> 
> gboolean (*cut_split_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*cut_txn_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*copy_split_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*copy_txn_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*paste_split_cb_fn)( GNCRegWidget*, gpointer user_data );
> gboolean (*paste_txn_cb_fn)( GNCRegWidget*, gpointer user_data );
> 
> gboolean (*style_change_cb_fn)( GNCRegWidget*,
>                                 style_type_t t,
>                                 gpointer user_data );
> _______________________________________________
> gnucash-devel mailing list
> gnucash-devel@lists.gnumatic.com
> http://www.gnumatic.com/cgi-bin/mailman/listinfo/gnucash-devel

-- 
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       warlord@MIT.EDU                        PGP key available