/** * The main controller (in a standard MVC point of view) of the application. It is a singleton * thus can be called by any part of the application. * This will wire all the commands that can be defined dynamically by any IView, and add their * corresponding buttons to the application menubar and toolbars. * See the "definitions" property documentation below for more info on how to define new commands. * * @author Charles du Jeu */ qx.Class.define("org.argeo.ria.event.CommandsManager", { type : "singleton", extend : qx.core.Object, construct : function(){ this.base(arguments); this.setInitialDefinitions(qx.lang.Object.copy(this.getDefinitions())); this.addListener("changedCommands", this.createCommands, this); }, properties : { /** * The commands definitions is a Map described as below *
* { * label : "", * | The label of the action * * icon : "", * | The icon image * * shortcut : "", * | The keyboard shortcut, as defined in qooxdoo (Control+s, Alt+k, etc.). Warning, the letter must be lowercase. * * enabled : true, * | Whether it is enabled or disabled at creation * * menu : ""|null, * | The menu group to which the command will be added. If null, will not appear in the menus. * * menuPosition : "first"|"last" * | Optional : force the menu group to be first or last in the menubar. * * toolbar : ""|null, * | The toolbar group to which the command will be added. If null, will not appear in the toolbars. * * init : function(){}, * | Optional function called at command creation. * | Function context : the command itself * * callback : function(e){}, * | The main callback to be triggered when command is executed. * | Function context : the current class (not the command!) * * selectionChange : function(viewPaneId, xmlNodes){}, * | Optional function called each time a selectionChange is detected in one of the active viewPane. * | The origin viewPaneId and the new selection as a map of nodes are passed as arguments. * | Function context : the command itself. * * submenu : [{label:"", icon:"", commandId:""}, ...], * | If set, the command will create a submenu, being in a menu or in the toolbar. * | The submenu is created with the various array entries, and the submenuCallback function * | will be called with the 'commandId' parameter when a submenu entry is selected. * * submenuCallback : function(commandId){}, * | Callback if command is a submenu (cf. above). * | Function context : the current class/ * * command : null * | For internal use only, caching the actual org.argeo.ria.event.Command object. * } ** @see org.argeo.ria.event.Command for the definition Map details. */ definitions : { init : { "stop" : { label : "Stop", icon : "resource/slc/process-stop.png", shortcut : "Control+s", enabled : false, menu : null, toolbar : "list", callback : function(e){}, command : null }, /* "quit" : { label : "Quit", icon : "resource/slc/system-shutdown.png", shortcut : "Control+q", enabled : true, menu : "File", toolbar : false, callback : function(e){}, command : null }, */ "log" : { label : "Show Console", icon : "resource/slc/help-contents.png", shortcut : "", enabled : true, menu : "Help", menuPosition: "last", toolbar : false, callback : function(e){ org.argeo.ria.components.Logger.getInstance().toggle(); }, command : null }, "help" : { label : "About...", icon : "resource/slc/help-about.png", shortcut : "Control+h", enabled : true, menu : "Help", toolbar : false, callback : function(e){ var win = new org.argeo.ria.components.Modal("About SLC", null, "SLC is a product from Argeo."); win.attachAndShow(); }, command : null } } }, /** * For internal use */ initialDefinitions : { init : {} } }, events : { /** * Triggered when the whole commands list is changed. Mainly used internally by the manager. */ "changedCommands" : "qx.event.type.Event" }, /* ***************************************************************************** MEMBERS ***************************************************************************** */ members : { /** * Creates all the objects (if they are not already existing) from the definitions maps. */ createCommands : function(){ this.menus = {}; this.toolbars = {}; var defs = this.getDefinitions(); for(var key in defs){ var definition = defs[key]; var command; if(!definition.command){ command = new org.argeo.ria.event.Command(key, definition.label, definition.icon, definition.shortcut); if(definition.submenu){ command.setMenu(definition.submenu); if(definition.submenuCallback){ command.setMenuCallback(definition.submenuCallback); command.setMenuContext((definition.callbackContext?definition.callbackContext:null)); } } command.setEnabled(definition.enabled); if(definition.toggle){ command.setToggle(true); } command.addListener("execute", definition.callback, (definition.callbackContext?definition.callbackContext:this)); if(definition.init){ var binded = qx.lang.Function.bind(definition.init, command); binded(); } definition.command = command; }else{ command = definition.command; } if(definition.menu){ if(!this.menus[definition.menu]) this.menus[definition.menu] = []; this.menus[definition.menu].push(definition); } if(definition.toolbar){ if(!this.toolbars[definition.toolbar]) this.toolbars[definition.toolbar] = []; this.toolbars[definition.toolbar].push(command); } } this.setDefinitions(defs); }, /** * Refresh the current commands status depending on the viewSelection. * @param viewSelection {org.argeo.ria.components.ViewSelection} The current ViewSelection */ refreshCommands : function(viewSelection){ var defs = this.getDefinitions(); var xmlNodes = null; if(viewSelection.getCount() > 0){ var xmlNodes = viewSelection.getNodes(); } for(var key in defs){ var definition = defs[key]; if(!definition.selectionChange) continue; var binded = qx.lang.Function.bind(definition.selectionChange, definition.command); binded(viewSelection.getViewId(), xmlNodes); } }, /** * Record a menubar for the application * @param menuBar {qx.ui.menubar.MenuBar} The application menubar */ registerMenuBar : function(menuBar){ this.addListener("changedCommands", function(){ this.createMenuButtons(menuBar); }, this); this.createMenuButtons(menuBar); }, /** * Record a toolbar for the application * @param toolBar {qx.ui.toolbar.ToolBar} The application toolbar */ registerToolBar : function(toolBar){ this.addListener("changedCommands", function(){ this.createToolbarParts(toolBar); }, this); this.createToolbarParts(toolBar); }, /** * Creates the real buttons and add them to the passed menuBar. * @param menuBar {qx.ui.menubar.MenuBar} The application menubar */ createMenuButtons : function(menuBar){ menuBar.removeAll(); var anchors = {}; for(var key in this.menus){ var menu = new qx.ui.menu.Menu(); var button = new qx.ui.menubar.Button(key, null, menu); var anchorDetected = false; for(var i=0; i