[RFI] GUI metadata for command args & options

Ian Clatworthy ian.clatworthy at canonical.com
Fri Jan 29 04:39:40 GMT 2010


For those who aren't aware, QBzr now has a cool dialog called qrun which
shows all available bzr commands, lets you select one and run it. The
commands are grouped by plugin. As you select each command, it displays
the help for it. It's actually a pretty cool way of browsing what a
plugin offers. It also means that all commands in all plugins are now
exposed to Explorer users.

One area where this dialog could be nicer is argument and option entry.
Currently, there's a text field for these and some standard "browse"
buttons for selecting a directory or files to add to that field. I'd
like to offer a "smart form" instead built from the metadata for the
actual Command object. (BTW, there's code in explorer now to build a
panel from a list of options. This is used to render workspace model
parameters in the Initialize dialog.)

Where's the best place to define this metadata? One option is to treat
the GUI presentation as a higher level layer and to put the metadata in
a separate location. Explorer now allows plugins to extend it by adding
files into an "explorer" directory within a plugin. We could use that
location to define smart forms in XML files.

OTOH, my gut feel here is that it's better to declare the metadata
inside each command. IMO, it's far more likely to be maintained then if
and when options are added or changed.

The sort of metadata I want is:

* a list property giving the order options appear and how to group them
  together

* a dict property providing style hints, e.g. combo vs radio buttons,
  text line vs text area.

Both would be optional. If an option is missing from the order list, it
would appear after those that are. If no style hint is given, a sensible
default would be applied.

Here's a sample for the commit command:

# This metadata is already provided ...
takes-args = ['selected*']
takes_options = [
    ListOption('exclude', type=str, short_name='x',
        help="Do not consider changes made to a given path."),
    Option('message', type=unicode,
           short_name='m',
           help="Description of the new revision."),
    'verbose',
     Option('unchanged',
            help='Commit even if nothing has changed.'),
     Option('file', type=str,
            short_name='F',
            argname='msgfile',
            help='Take commit message from this file.'),
     Option('strict',
            help="Refuse to commit if there are unknown "
            "files in the working tree."),
     Option('commit-time', type=str,
            help="Manually set a commit time using commit date "
            "format, e.g. '2009-10-10 08:00:00 +0100'."),
     ListOption('fixes', type=str,
            help="Mark a bug as being fixed by this revision "
                 "(see \"bzr help bugs\")."),
     ListOption('author', type=unicode,
            help="Set the author's name, if it's different "
                 "from the committer."),
     Option('local',
            help="Perform a local commit in a bound "
                 "branch.  Local commits are not pushed to "
                 "the master branch until a normal commit "
                 "is performed."
            ),
     Option('show-diff',
            help='When no message is supplied, show the diff along'
            ' with the status summary in the message editor.'),
     ]

# This metadata is new ...
ui_ordering = [
    'verbose',
    ('Message', ['message', 'file', 'show-diff']),
    ('Properties', ['author', 'fixes', 'commit-time']),
    ('Advanced', ['strict', 'unchanged', 'local', exclude']),
    ]
ui_styles = {
    'selected': 'paths',
    'message': 'multi-line',
    'file': 'file',
    'author': 'user-id',
    'commit-time': 'timestamp',
    'exclude': 'paths',
    'Advanced': 'collapsed',
    }

Note: There will always be the need for custom dialog boxes for heavily
used commands: this extra metadata isn't a universal answer to providing
a compelling UI. What it does offer though is a much improved experience
(over a text entry box for typing arguments and options) and it means
commands in plugins have a good enough UI with very little effort on the
part of the plugin developer.

Thoughts?

Ian C.



More information about the bazaar mailing list