I have a command in my McCLIM application that allows the user to set pathname defaults:
(define-taems-mdp-app-command (com-change-taems-filename-defaults :name t) ((pathname 'directory-pathname :default (make-pathname :directory (pathname-directory (taems-pathname-defaults *application-frame*))) :prompt "New default TAEMS model directory?")) ...)
You will see that it takes one argument.
I have put it in the file menu of my application, and when I try to invoke it, McCLIM crashes with the following error:
Error: KAUAI-GRAPHER::COM-CHANGE-TAEMS-FILENAME-DEFAULTS got 0 args, wanted 1 arg. [condition type: PROGRAM-ERROR]
Restart actions (select using :continue): 0: Return to application command loop 1: Abort entirely from this (lisp) process. [Current process: TAEMS CLIM Grapher] [1] CL-USER(1): :bt Evaluation stack:
GRAPH-MDP::COM-CHANGE-TAEMS-FILENAME-DEFAULTS <- (METHOD CLIM:EXECUTE-FRAME-COMMAND (CLIM:APPLICATION-FRAME T)) <- (METHOD CLIM:DEFAULT-FRAME-TOP-LEVEL (CLIM:APPLICATION-FRAME)) <- (:INTERNAL (:EFFECTIVE-METHOD 1 T ...) 0) <- (:INTERNAL (MOP:CLASS-DEFAULT-INITARGS GRAPH-MDP::TAEMS-MDP-APP :TOP-LEVEL-LAMBDA) 0) <- (METHOD CLIM:RUN-FRAME-TOP-LEVEL (CLIM:APPLICATION-FRAME)) <- (METHOD CLIM:RUN-FRAME-TOP-LEVEL :AROUND ...) <- (:INTERNAL (:EFFECTIVE-METHOD 1 T ...) 0) <- (:INTERNAL GRAPH-MDP:RUN-GRAPHER 0)
My understanding from reading the manual is that when I invoke this command from the menu, it should prompt me to accept the arguments.
add-menu-item-to-command-table [Function] Arguments: command-table string type value &key documentation (after :end) keystroke text-style (errorp t) button-type s Adds a command menu item to command-table's menu. The arguments are: command-table Can be either a command table or a symbol that names a command table. string The name of the command menu item. The character case and style of string are ignored. This is how the item will appear in the menu. type This is one of: :command, :menu, or :divider. (:function, called for in the CLIM spec, is not supported in this release.) When type is :command, value should be a command (a cons of a command name followed by a list of the command's arguments), or a command name. (When value is a command name, it behaves as though a command with no arguments was supplied.) In the case where all of the command's required arguments are supplied, clicking a command menu item invokes the command immediately. Otherwise, the user will be prompted for the remaining required arguments.
[from the Allegro CLIM manual; the online spec has similar wording.]
Can anyone say why McCLIM is crashing here? It seems like the read-frame-command :around method should have invoked command-line-remaining-arguments-for-partial-command. The code is here:
(defmethod read-frame-command :around ((frame application-frame) &key (stream *standard-input*)) (with-input-context ('menu-item) (object) (call-next-method) (menu-item (let ((command (command-menu-item-value object))) (unless (listp command) (setq command (list command))) (if (and (typep stream 'interactor-pane) (member *unsupplied-argument-marker* command :test #'eq)) (command-line-read-remaining-arguments-for-partial-command (frame-command-table frame) stream command 0) command)))))
Is it possible that the stream is not an interactor-pane when the menu item is selected?
For other commands, I have kludged around this problem and made them take no arguments and just accept them "by hand," as it were...
Any help would be much appreciated.
thanks, R
A quick follow-up: this problem only occurs when I invoke my command from the menu-bar (i.e., from a submenu in the "File" menu on the menubar). When I invoke the command by using the menu I get with the right-button on the application window, McCLIM prompts for commands properly.
So have I misunderstood how to use the menu bar? Or is this a bug?
Many thanks, Robert
Robert Goldman wrote:
A quick follow-up: this problem only occurs when I invoke my command from the menu-bar (i.e., from a submenu in the "File" menu on the menubar). When I invoke the command by using the menu I get with the right-button on the application window, McCLIM prompts for commands properly.
So have I misunderstood how to use the menu bar? Or is this a bug?
Many thanks, Robert _______________________________________________ mcclim-devel mailing list mcclim-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/mcclim-devel
OK, I think that this is a real bug. The problem is that when you select a command from a menu item, if it's a command that takes arguments, and you haven't provided values for them, McCLIM reads the command as (<command-name>) and pukes on the missing argument(s).
The problem is that it *should* be reading such a command as:
(<command-name> <unsupplied-argument-marker>^n)
for n being the number of arguments to the command.
I have a patch that will make this happen properly:
Index: frames.lisp =================================================================== RCS file: /project/mcclim/cvsroot/mcclim/frames.lisp,v retrieving revision 1.125 diff -b -u -F^(def -r1.125 frames.lisp --- frames.lisp 7 Feb 2007 12:44:16 -0000 1.125 +++ frames.lisp 2 Mar 2007 21:52:13 -0000 @@ -505,9 +505,9 @@ (defmethod read-frame-command :around (( (menu-item (let ((command (command-menu-item-value object))) (unless (listp command) - (setq command (list command))) + (setq command (partial-command-from-name command))) (if (and (typep stream 'interactor-pane) - (member *unsupplied-argument-marker* command :test #'eq)) + (partial-command-p command)) (command-line-read-remaining-arguments-for-partial-command (frame-command-table frame) stream command 0) command)))))
I will also attach it for fear mailers that word-wrap will garble it...
Any feedback would be welcome. This works for me, but isn't even what I'd laughingly call "tested."
R
Index: frames.lisp =================================================================== RCS file: /project/mcclim/cvsroot/mcclim/frames.lisp,v retrieving revision 1.125 diff -b -u -F^(def -r1.125 frames.lisp --- frames.lisp 7 Feb 2007 12:44:16 -0000 1.125 +++ frames.lisp 2 Mar 2007 21:56:05 -0000 @@ -505,9 +505,9 @@ (defmethod read-frame-command :around (( (menu-item (let ((command (command-menu-item-value object))) (unless (listp command) - (setq command (list command))) + (setq command (partial-command-from-name command))) (if (and (typep stream 'interactor-pane) - (member *unsupplied-argument-marker* command :test #'eq)) + (partial-command-p command)) (command-line-read-remaining-arguments-for-partial-command (frame-command-table frame) stream command 0) command)))))
Robert Goldman rpgoldman@real-time.com writes:
I have a patch that will make this happen properly:
Comprehensive testing[1] and some quick reasoning tells me your patch should work. I just committed it. Thanks!
[1] Not really.