I have a top menu that looks like this:
File Edit Operation etc. Open Cut Undo etc. etc. Redo I want to change the Undo and Redo to have them say just what they are about to undo or redo, e.g. 'Undo Remove class Foo'. I have managed to grab the CommandMenuItem object and can change its description. What I don't know how to do is get the menu to refresh itself to reflect the changes. Note that I am -not- talking about popup menus here. Thanks. Donald |
Donald
You wrote in message news:984dg4$mm6$[hidden email]... > I have a top menu that looks like this: > > File Edit Operation etc. > Open Cut Undo > etc. etc. Redo > > I want to change the Undo and Redo to have them say > just what they are about to undo or redo, e.g. > 'Undo Remove class Foo'. I have managed to grab > the CommandMenuItem object and can change its > description. What I don't know how to do is get the > menu to refresh itself to reflect the changes. This sort of thing is done in #queryCommand: along with enablement/disablement, e.g. see MethodBrowser>>queryCommand:, specifically the handling of the #browseMethodClass command (4.0 has quite a lot of examples, but I don't think they are in 3.0). The commands will all be "queried" (i.e. the #queryCommand: methods of Presenters, Views and Models on the command route will be invoked) when a menu is opened, so you generally don't need to explicitly state that this needs to be done. Sometimes it is necessary for commands that appear on toolbar buttons - see senders of #invalidateUserInterface, many of which are part of the framework and triggered at appropriate times such as changes of selection, the execution of a command, etc, the overall result of which is that it isn't often needed in one's own presenters. > > Note that I am -not- talking about popup menus here. > Thanks. Changing the #text: of a CommandQuery will affect all places that use that same command, so if the same commands appear on a context menu then those too would be updated. Generally though one places context-sensitive commands on the context menu (e.g. #browse, #delete), but one puts more specific commands on the menu bar (e.g. #browseThis or #deleteThat) because one typically doesn't want the menu bar to do different things depending on the selection. Regards Blair |
Blair,
Thanks for your usual lucid explanation. I was mucking about in queryCommand, but I was modifying description instead of text. It's always fun putting self halts in a queryCommand:. I even remember to save my image first, most of this time. Thanks. Donald "Blair McGlashan" <[hidden email]> wrote in message news:985l9k$dbaf$[hidden email]... > Donald > > You wrote in message news:984dg4$mm6$[hidden email]... > > I have a top menu that looks like this: > > > > File Edit Operation etc. > > Open Cut Undo > > etc. etc. Redo > > > > I want to change the Undo and Redo to have them say > > just what they are about to undo or redo, e.g. > > 'Undo Remove class Foo'. I have managed to grab > > the CommandMenuItem object and can change its > > description. What I don't know how to do is get the > > menu to refresh itself to reflect the changes. > > This sort of thing is done in #queryCommand: along with > enablement/disablement, e.g. see MethodBrowser>>queryCommand:, > the handling of the #browseMethodClass command (4.0 has quite a lot of > examples, but I don't think they are in 3.0). > > The commands will all be "queried" (i.e. the #queryCommand: methods of > Presenters, Views and Models on the command route will be invoked) when a > menu is opened, so you generally don't need to explicitly state that this > needs to be done. Sometimes it is necessary for commands that appear on > toolbar buttons - see senders of #invalidateUserInterface, many of which are > part of the framework and triggered at appropriate times such as changes of > selection, the execution of a command, etc, the overall result of which is > that it isn't often needed in one's own presenters. > > > > > Note that I am -not- talking about popup menus here. > > Thanks. > > Changing the #text: of a CommandQuery will affect all places that use that > same command, so if the same commands appear on a context menu then those > too would be updated. > Generally though one places context-sensitive commands on the context menu > (e.g. #browse, #delete), but one puts more specific commands on the menu > (e.g. #browseThis or #deleteThat) because one typically doesn't want the > menu bar to do different things depending on the selection. > > Regards > > Blair > > |
Donald
You wrote in message news:986rvm$atn$[hidden email]... >... > I was mucking about in queryCommand, but I was > modifying description instead of text. If you do that you'll be modifying the underlying static description of the command, which is probably not what you want. > ... > It's always fun putting self halts in a queryCommand:. > I even remember to save my image first, most of > this time. :-). Breaking in #queryCommand: can be problematic because it is often called during idle time to validate toolbar buttons etc. This occurs when the #invalidateUserInterface message has been used to mark a window's command enablement state as being in need of update. If this "validation" is not allowed to complete, then the request is repeated until it is, and consequently one can get a lot of walkbacks very quickly, usually culminating in an untimely exit once resources have been exhausted. It is possible to debug through queryCommand:, but one has to take care. Here are a couple of tips: 1) Don't insert an unconditional breakpoint at the outermost scope - very rapidly appearing walkbacks will result. Inserting the breakpoint inside one of the command conditions will also result in multiple walkbacks, but usually one can generally resume one of them (thus validating the UI of the shell), and then use another of the walkbacks to start up the debugger. 2) Use a conditional breakpoint (especially if you really want to insert a breakpoint at the outermost scope). This can be easily achieved using a global variable and an expression such as 'A isNil ifTrue: [A := 1. self halt]', which will only break the first time through, allowing one to then debug away. One can reset the condition to have it fire again by setting the variable to nil once more. 3) If a breakpoint in #queryCommand: is hit as a result of opening a menu (which also initiates a command validation cycle) then you may find that operation of the mouse and/or keyboard is impaired. This is because Windows enters a very modal state when a menu is popped and it snaffles up some input events. On WinNT/2K it is possible to get out of this modal state by switching away to another application and back, e.g. using Atl+Tab. I can't remember if this trick works on 95/98, but I have a feeling it doesn't. There used to be a similar repeating walkback problem with setting breakpoints in "paint" methods, although in that case death was even more rapid. We worked around this issue by deliberately validating any view with a WM_PAINT message on the stack when a walkback occurs, thus preventing repeating WM_PAINT messages from Windows. One side effect of this is that Windows may occassionally not repaint properly after a walkback, but this was deemed acceptable at development time. It occurs to me that we probably ought to employ a similar workaround for #queryCommand:, and "validate" the user interface of any shell on the stack in a queryCommand: when a walkback occurs, either due to a deliberately inserted break, or an error. I will enter it onto our bugs system. Regards Blair |
Free forum by Nabble | Edit this page |