* thus can be called by any part of the application.\r
* This will wire all the commands that can be defined dynamically by any IView, and add their\r
* corresponding buttons to the application menubar and toolbars.\r
+ * See the "definitions" property documentation below for more info on how to define new commands.\r
* \r
* @author Charles du Jeu\r
*/\r
properties : \r
{\r
/**\r
- * Commands definitions\r
+ * The commands definitions is a Map described as below\r
+ * <pre>\r
+ * {\r
+ * <b>label : "",</b> \r
+ * | The label of the action\r
+ * \r
+ * <b>icon : "",</b> \r
+ * | The icon image\r
+ * \r
+ * <b>shortcut : "",</b>\r
+ * | The keyboard shortcut, as defined in qooxdoo (Control+s, Alt+k, etc.). Warning, the letter must be lowercase.\r
+ * \r
+ * <b>enabled : true,</b>\r
+ * | Whether it is enabled or disabled at creation\r
+ * \r
+ * <b>menu : ""|null,</b>\r
+ * | The menu group to which the command will be added. If null, will not appear in the menus.\r
+ * \r
+ * <b>menuPosition : "first"|"last"</b>\r
+ * | Optional : force the menu group to be first or last in the menubar.\r
+ * \r
+ * <b>toolbar : ""|null,</b>\r
+ * | The toolbar group to which the command will be added. If null, will not appear in the toolbars.\r
+ * \r
+ * <b>init : function(){},</b>\r
+ * | Optional function called at command creation.\r
+ * | Function context : the command itself\r
+ * \r
+ * <b>callback : function(e){},</b>\r
+ * | The main callback to be triggered when command is executed.\r
+ * | Function context : the current class (not the command!)\r
+ * \r
+ * <b>selectionChange : function(viewPaneId, xmlNodes){},</b>\r
+ * | Optional function called each time a selectionChange is detected in one of the active viewPane.\r
+ * | The origin viewPaneId and the new selection as a map of nodes are passed as arguments.\r
+ * | Function context : the command itself.\r
+ * \r
+ * <b>submenu : [{label:"", icon:"", commandId:""}, ...],</b>\r
+ * | If set, the command will create a submenu, being in a menu or in the toolbar.\r
+ * | The submenu is created with the various array entries, and the submenuCallback function\r
+ * | will be called with the 'commandId' parameter when a submenu entry is selected.\r
+ * \r
+ * <b>submenuCallback : function(commandId){},</b>\r
+ * | Callback if command is a submenu (cf. above).\r
+ * | Function context : the current class/\r
+ * \r
+ * <b>command : null</b>\r
+ * | For internal use only, caching the actual org.argeo.ria.event.Command object.\r
+ * }\r
+ * </pre>\r
* @see org.argeo.ria.event.Command for the definition Map details. \r
*/\r
definitions : {\r
- init : {\r
- "stop" : {\r
- label : "Stop", \r
- icon : "resource/slc/process-stop.png",\r
- shortcut : "Control+s",\r
- enabled : false,\r
- menu : null,\r
- toolbar : "list",\r
- callback : function(e){},\r
- command : null\r
- },\r
- /*\r
- "quit" : {\r
- label : "Quit", \r
- icon : "resource/slc/system-shutdown.png",\r
- shortcut : "Control+q",\r
- enabled : true,\r
- menu : "File",\r
- toolbar : false,\r
- callback : function(e){}, \r
- command : null\r
- },\r
- */\r
- "log" : {\r
- label : "Show Console", \r
- icon : "resource/slc/help-contents.png",\r
- shortcut : "",\r
- enabled : true,\r
- menu : "Help",\r
- menuPosition: "last",\r
- toolbar : false,\r
- callback : function(e){ \r
- org.argeo.ria.components.Logger.getInstance().toggle();\r
- }, \r
- command : null\r
- },\r
- "help" : {\r
- label : "About...", \r
- icon : "resource/slc/help-about.png",\r
- shortcut : "Control+h",\r
- enabled : true,\r
- menu : "Help",\r
- toolbar : false,\r
- callback : function(e){\r
- var win = new org.argeo.ria.components.Modal("About SLC", null, "SLC is a product from Argeo.");\r
- win.attachAndShow();\r
- }, \r
- command : null\r
- }\r
- }\r
+ init : {},\r
+ check : "Map"\r
},\r
/**\r
* For internal use \r
*/\r
initialDefinitions : {\r
- init : {}\r
+ init : {},\r
+ check : "Map"\r
+ },\r
+ sharedDefinitions : {\r
+ init: {},\r
+ check: "Map"\r
}\r
},\r
\r
events : {\r
/**\r
- * Triggered when the whole commands list is changed.\r
+ * Triggered when the whole commands list is changed. Mainly used internally by the manager.\r
*/\r
"changedCommands" : "qx.event.type.Event"\r
},\r
\r
members :\r
{\r
+ init : function(initDefinitions){\r
+ this.setDefinitions(initDefinitions);\r
+ this.setInitialDefinitions(qx.lang.Object.copy(initDefinitions));\r
+ },\r
+ \r
/**\r
* Creates all the objects (if they are not already existing) from the definitions maps.\r
*/\r
this.menus = {};\r
this.toolbars = {};\r
var defs = this.getDefinitions();\r
+ var shared = this.getSharedDefinitions();\r
for(var key in defs){\r
var definition = defs[key];\r
var command;\r
if(definition.toggle){\r
command.setToggle(true);\r
}\r
- command.addListener("execute", definition.callback, (definition.callbackContext?definition.callbackContext:this));\r
+ this._attachListener(command, definition.callback, definition.callbackContext);\r
if(definition.init){\r
var binded = qx.lang.Function.bind(definition.init, command);\r
binded();\r
definition.command = command;\r
}else{\r
command = definition.command;\r
+ if(shared[key]){\r
+ \r
+ for(var focusPartId in shared[key]){\r
+ var sharedCommand = shared[key][focusPartId];\r
+ if(sharedCommand.callback){\r
+ var split = sharedCommand.callbackContext.split(":");\r
+ var focusPart = split[0];\r
+ var viewId = split[1]; \r
+ command.registerCallback(sharedCommand.callback, split[1]); \r
+ //this._attachListener(command, sharedCommand.callback, sharedCommand.callbackContext);\r
+ } \r
+ }\r
+ \r
+ }\r
}\r
if(definition.menu){\r
if(!this.menus[definition.menu]) this.menus[definition.menu] = [];\r
*/\r
refreshCommands : function(viewSelection){\r
var defs = this.getDefinitions();\r
+ var shared = this.getSharedDefinitions();\r
var xmlNodes = null;\r
if(viewSelection.getCount() > 0){\r
var xmlNodes = viewSelection.getNodes();\r
for(var key in defs){\r
var definition = defs[key];\r
if(!definition.selectionChange) continue;\r
+ if(shared[key]){\r
+ var currentFocus = org.argeo.ria.components.ViewsManager.getInstance().getCurrentFocus();\r
+ if(!currentFocus) continue;\r
+ var sharedComm = shared[key][currentFocus.getViewId()];\r
+ if(sharedComm && sharedComm.selectionChange){\r
+ var binded = qx.lang.Function.bind(sharedComm.selectionChange, definition.command);\r
+ binded(viewSelection.getViewId(), xmlNodes);\r
+ }\r
+ }\r
var binded = qx.lang.Function.bind(definition.selectionChange, definition.command);\r
binded(viewSelection.getViewId(), xmlNodes);\r
}\r
return contextMenu;\r
},\r
/**\r
- * Add a new set of commands definitions\r
+ * Add a new set of commands definitions. See the definitions property of this class.\r
* @param definitions {Map} a set of commands definitions.\r
- * @param callbackContext {qx.ui.core.Object} The context used inside the commands callbacks.\r
+ * @param callbackContext {qx.ui.core.Object} The context used inside the commands callbacks. \r
*/\r
- addCommands : function(definitions, callbackContext){\r
+ addCommands : function(definitions, callbackContext, focusablePartId){\r
var crtDefs = this.getDefinitions(); \r
for(var key in definitions){\r
if(callbackContext) definitions[key]['callbackContext'] = callbackContext;\r
- crtDefs[key] = definitions[key];\r
+ if(crtDefs[key] && definitions[key]['shared']){\r
+ if(focusablePartId) {\r
+ definitions[key]['focusablePartId'] = focusablePartId;\r
+ if(!this.getSharedDefinitions()[key]){\r
+ this.getSharedDefinitions()[key] = {};\r
+ }\r
+ this.getSharedDefinitions()[key][focusablePartId] = definitions[key];\r
+ }\r
+ \r
+ }else{\r
+ crtDefs[key] = definitions[key];\r
+ }\r
}\r
this.setDefinitions(crtDefs);\r
this.fireEvent("changedCommands");\r
* Removes a whole set of commands by their definitions maps.\r
* @param definitions {Map} a set of commands definitions\r
*/\r
- removeCommands : function(definitions){\r
+ removeCommands : function(definitions, focusablePartId){\r
var crtDefs = this.getDefinitions();\r
var initDefs = this.getInitialDefinitions();\r
+ var sharedDefs = this.getSharedDefinitions();\r
for(var key in definitions){\r
if(!crtDefs[key]) continue;\r
if(initDefs[key]){\r
crtDefs[key] = initDefs[key];\r
}else{\r
- delete crtDefs[key];\r
+ if(sharedDefs[key] && sharedDefs[key][focusablePartId]){\r
+ crtDefs[key].command.removeCallback(focusablePartId);\r
+ delete sharedDefs[key][focusablePartId];\r
+ }else{\r
+ delete crtDefs[key];\r
+ }\r
}\r
}\r
this.setDefinitions(crtDefs);\r
this.setShow(e.getData());\r
}, toolbar);\r
\r
+ },\r
+ /**\r
+ * Attach a listener to a command, with a context.\r
+ * The context can be an object, a string like "view:viewId" or null. \r
+ * If a string, the viewPaneId content will be retrieved at runtime. If null, "this" will be used\r
+ * as default context.\r
+ * @param command {org.argeo.ria.event.Command} The command\r
+ * @param callback {Function} The function to execute\r
+ * @param callbackContext {Object|String} The context in which the function will be executed. \r
+ */\r
+ _attachListener:function(command, callback, callbackContext){ \r
+ if(!callbackContext){\r
+ command.addListener("execute", callback, this);\r
+ return;\r
+ }\r
+ if(typeof(callbackContext) == "object"){\r
+ command.addListener("execute", callback, callbackContext);\r
+ return;\r
+ } \r
+ if(typeof(callbackContext) == "string"){\r
+ \r
+ var split = callbackContext.split(":");\r
+ var focusPart = split[0];\r
+ var viewId = split[1];\r
+ if(command.getCallbacks()[viewId]) return;\r
+ command.registerCallback(callback, split[1]);\r
+ command.addListener("execute", function(event){\r
+ var target = event.getTarget();\r
+ var callbacks = target.getCallbacks();\r
+ if(qx.lang.Object.getLength(callbacks) == 0) return;\r
+ var view = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById(viewId).getContent();\r
+ if(qx.lang.Object.getLength(callbacks) == 1){\r
+ var binded = qx.lang.Function.bind(callbacks[qx.lang.Object.getKeys(callbacks)[0]], view);\r
+ binded(event);\r
+ return;\r
+ }\r
+ var currentFocus = org.argeo.ria.components.ViewsManager.getInstance().getCurrentFocus();\r
+ if(currentFocus && currentFocus.getViewId() && callbacks[currentFocus.getViewId()]){\r
+ var binded = qx.lang.Function.bind(callbacks[currentFocus.getViewId()], view);\r
+ binded(event);\r
+ return;\r
+ }\r
+ });\r
+ \r
+ \r
+ /*\r
+ if(callbackContext.split(":")[0] == "view"){\r
+ var viewId = callbackContext.split(":")[1];\r
+ command.addListener("execute", function(event){\r
+ if(event.getTarget().getCheckFocusAtCallback()){\r
+ var currentFocus = org.argeo.ria.components.ViewsManager.getInstance().getCurrentFocus();\r
+ if(currentFocus.getViewId() != viewId) return;\r
+ }\r
+ var view = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById(viewId).getContent();\r
+ var binded = qx.lang.Function.bind(callback, view);\r
+ binded(event);\r
+ });\r
+ }else{\r
+ command.addListener("execute", callback, callbackContext);\r
+ }\r
+ */\r
+ }\r
}\r
}\r
-});
\ No newline at end of file
+});\r