On 6/13/07 8:07 AM, "Glynn Clements" <glynn@gclements.plus.com> wrote:
Michael Barton wrote:
d.* commands used as map layers belong in a separate menu. The menu
items for layer commands should have different bindings to normal
commands.
Determining how to run a command based upon its name is simply wrong.
This is needed, at least in some spots to permit running d.* commands from
the CLI. That's why it needs to look at the name.
No, it's needed to force d.* commands to be intercepted and used to
create layers. It won't work if the d.* command isn't suitable as a
layer command (e.g. d.rast.edit). It also precludes running d.*
commands normally (i.e. using a monitor).
Ignoring the last point, determining whether or not a command can be
used as a layer command isn't as simple as matching against "d.*".
Clarification.
No d.* commands come from the menus, except for d.rast.edit and some old
ones that need xmons. The latter are specially routed through the OnXterm
method and never are parsed by menuform.py. d.rast.edit is the only weird
exception solely because you made a nice gui for it.
"Normal" menu commands are all those that are not display commands and have
no arguments. Explicitly in the menu, these are processed by OnMenuCmd in
wxgui.py. They are sent to the menuform.py parser. d.* commands (e.g.,
d.rast, d.grid, etc) are simply not in the menu as a general rule because
they need to handled differently, as you say.
Menu commands with arguments (e.g., g.region -p) are explicitly handled by
RunMenuCmd, which simply sends them on to the command processor (ultimately
cmd.Command(cmdlist), rather than menuform.py.
Menu commands which call wxPython modules have their own handlers (e.g.,
histogramming or the new rules dialogs).
Menu commands which require an xterm (a few like r.digit) are handled by the
new OnXTerm method, which launches an xmon and xterm.
Jachym and others have been working on some Python scripts (e.g., p.mon) to
give access to some the of the wxgrass functions from the *nix terminal. I
don't really know how these function. The d.* trap within menuform.py may be
related to these or it may be a holdover from an earlier iteration that
should be dropped.
For the CLI built into wxgrass (the one I DO know about), here is the
parsing logic.
A list of GRASS CLI commands is made by searching $GISBASE/bin and
$GISBASE/scripts.
If the first part (i.e., before the first space) of a string typed on the
CLI is not in the list, it is passed on to the shell.
If first part of the string IS in the GRASS command list, it is treated as a
GRASS command. I realize that the following is not ideal, but it's the best
I've been able to come up with so far and covers the great majority of
cases. Suggestions for improvements are welcome.
GRASS command parsing from the wxgrass CLI:
Split the command into a list by spaces. I realize that this is a problem
for any command with spaces in the arguments, but I know of no better way to
do this in this context outside of making users type any command as a Python
list. If we made people type ['g.region', 'rast=mymap', 'res=30'] instead of
g.region rast=mymap res=30, I don't think anyone would want to use the CLI.
If the command has no arguments (i.e., len(cmdlist) == 0) AND it is NOT a
d.* command, send the original command string (not the list) to the
menuform.py processor (just like the menu would) to create the autogenerated
properties dialog. After this, the result of hitting "run" is the same as if
the properties dialog were called from the menu.
If the command has no arguments AND IS a d.* command AND is in a hard coded
list of d.* commands for which we have defined layers in the layer tree,
create a layer tree item for that command (e.g., a raster layer for d.rast).
After that, the new layer is processed in the same way as one created by
pressing a layer button on the layer manager toolbar.
If the d.* command without arguments is NOT on the list for the layer tree,
generate get a message that it cannot be processed.
If the command HAS arguments and is NOT a d.* command, send the command list
(i.e., made by splitting on spaces -- not the original command string) to
cmd.Command for processing.
If the command HAS arguments and IS a d.* command, it is added to the list
of display layers managed within render.py for the map display that has the
focus and the UpdateMap method is called to update that display. There is a
2nd splitting that allows for multiple d.* commands to be separated by
semi-colons. This may or may not be a good idea in the end, but I thought
I'd see how it worked out.
If it was only from the menu, then it would be easy. I don't know if this is
the case in menuform. I don't know exactly what is going on in this spot and
haven't had time yet to figure it out.
The name "menuform.py" suggests that it has something to do with
menus. In which case, what is:
if cmd[0][0:2] != "d.":
doing in that file (specifically, in mainFrame.OnRun())?
I don't know.
menuform.py parses the --interface-description xml data to create a
properties dialog. The dialog takes the results of user choices and creates
a command list for processing--ulitmately by cmd.Command.
Even if you are determined to use that hack for the CLI, it has no
utility in regard to menus.
I just don't know if it is related to the p.mon, p.rast, etc scripts or
whether it can simply be removed.
Michael
__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University
phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton