]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.webapp/src/main/webapp/source/class/org/argeo/ria/event/CommandsManager.js
7bd0957dd7d430605674f4ad9c1cc7456b497f87
[gpl/argeo-slc.git] / org.argeo.slc.webapp / src / main / webapp / source / class / org / argeo / ria / event / CommandsManager.js
1 /**
2 * The main controller (in a standard MVC point of view) of the application. It is a singleton
3 * thus can be called by any part of the application.
4 * This will wire all the commands that can be defined dynamically by any IView, and add their
5 * corresponding buttons to the application menubar and toolbars.
6 *
7 * @author Charles du Jeu
8 */
9 qx.Class.define("org.argeo.ria.event.CommandsManager",
10 {
11 type : "singleton",
12 extend : qx.core.Object,
13
14 construct : function(){
15 this.base(arguments);
16 this.setInitialDefinitions(qx.lang.Object.copy(this.getDefinitions()));
17 this.addListener("changedCommands", this.createCommands, this);
18 },
19
20 properties :
21 {
22 /**
23 * Commands definitions
24 * @see org.argeo.ria.event.Command for the definition Map details.
25 */
26 definitions : {
27 init : {
28 "stop" : {
29 label : "Stop",
30 icon : "resource/slc/process-stop.png",
31 shortcut : "Control+s",
32 enabled : false,
33 menu : null,
34 toolbar : "list",
35 callback : function(e){},
36 command : null
37 },
38 "quit" : {
39 label : "Quit",
40 icon : "resource/slc/system-shutdown.png",
41 shortcut : "Control+q",
42 enabled : true,
43 menu : "File",
44 toolbar : false,
45 callback : function(e){},
46 command : null
47 },
48 "log" : {
49 label : "Show Console",
50 icon : "resource/slc/help-contents.png",
51 shortcut : "",
52 enabled : true,
53 menu : "Help",
54 menuPosition: "last",
55 toolbar : false,
56 callback : function(e){
57 org.argeo.ria.components.Logger.getInstance().toggle();
58 },
59 command : null
60 },
61 "help" : {
62 label : "About...",
63 icon : "resource/slc/help-about.png",
64 shortcut : "Control+h",
65 enabled : true,
66 menu : "Help",
67 toolbar : false,
68 callback : function(e){
69 var win = new org.argeo.ria.components.Modal("About SLC", null, "SLC is a product from Argeo.");
70 win.attachAndShow();
71 },
72 command : null
73 }
74 }
75 },
76 /**
77 * For internal use
78 */
79 initialDefinitions : {
80 init : {}
81 }
82 },
83
84 events : {
85 /**
86 * Triggered when the whole commands list is changed.
87 */
88 "changedCommands" : "qx.event.type.Event"
89 },
90
91 /*
92 *****************************************************************************
93 MEMBERS
94 *****************************************************************************
95 */
96
97 members :
98 {
99 /**
100 * Creates all the objects (if they are not already existing) from the definitions maps.
101 */
102 createCommands : function(){
103 this.menus = {};
104 this.toolbars = {};
105 var defs = this.getDefinitions();
106 for(var key in defs){
107 var definition = defs[key];
108 var command;
109 if(!definition.command){
110 command = new org.argeo.ria.event.Command(key, definition.label, definition.icon, definition.shortcut);
111 if(definition.submenu){
112 var menu = new qx.ui.menu.Menu();
113 command.setMenu(menu);
114 if(definition.submenuCallback){
115 command.setMenuCallback(definition.submenuCallback);
116 command.setMenuContext((definition.callbackContext?definition.callbackContext:null));
117 }
118 }
119 command.setEnabled(definition.enabled);
120 command.addListener("execute", definition.callback, (definition.callbackContext?definition.callbackContext:this));
121 definition.command = command;
122 }else{
123 command = definition.command;
124 }
125 if(definition.menu){
126 if(!this.menus[definition.menu]) this.menus[definition.menu] = [];
127 this.menus[definition.menu].push(definition);
128 }
129 if(definition.toolbar){
130 if(!this.toolbars[definition.toolbar]) this.toolbars[definition.toolbar] = [];
131 this.toolbars[definition.toolbar].push(command);
132 }
133 }
134 this.setDefinitions(defs);
135 },
136
137 /**
138 * Refresh the current commands status depending on the viewSelection.
139 * @param viewSelection {org.argeo.ria.components.ViewSelection} The current ViewSelection
140 */
141 refreshCommands : function(viewSelection){
142 var defs = this.getDefinitions();
143 var xmlNodes = null;
144 if(viewSelection.getCount() > 0){
145 var xmlNodes = viewSelection.getNodes();
146 }
147 for(var key in defs){
148 var definition = defs[key];
149 if(!definition.selectionChange) continue;
150 var binded = qx.lang.Function.bind(definition.selectionChange, definition.command);
151 binded(viewSelection.getViewId(), xmlNodes);
152 }
153 },
154
155 /**
156 * Record a menubar for the application
157 * @param menuBar {qx.ui.menubar.MenuBar} The application menubar
158 */
159 registerMenuBar : function(menuBar){
160 this.addListener("changedCommands", function(){
161 this.createMenuButtons(menuBar);
162 }, this);
163 this.createMenuButtons(menuBar);
164 },
165
166 /**
167 * Record a toolbar for the application
168 * @param toolBar {qx.ui.toolbar.ToolBar} The application toolbar
169 */
170 registerToolBar : function(toolBar){
171 this.addListener("changedCommands", function(){
172 this.createToolbarParts(toolBar);
173 }, this);
174 this.createToolbarParts(toolBar);
175 },
176
177 /**
178 * Creates the real buttons and add them to the passed menuBar.
179 * @param menuBar {qx.ui.menubar.MenuBar} The application menubar
180 */
181 createMenuButtons : function(menuBar){
182 menuBar.removeAll();
183 var anchors = {};
184 for(var key in this.menus){
185 var menu = new qx.ui.menu.Menu();
186 var button = new qx.ui.menubar.Button(key, null, menu);
187 var anchorDetected = false;
188 for(var i=0; i<this.menus[key].length;i++){
189 var def = this.menus[key][i];
190 menu.add(def.command.getMenuButton());
191 if(!anchorDetected && def.menuPosition){
192 anchorDetected = true;
193 anchors[def.menuPosition] = button;
194 }
195 }
196 if(!anchorDetected){
197 menuBar.add(button);
198 }
199 }
200 // Add specific anchored buttons
201 if(anchors.first) menuBar.addAt(anchors.first, 0);
202 else if(anchors.last){
203 menuBar.add(anchors.last);
204 }
205 },
206
207 /**
208 * Creates the real buttons and add them to the passed toolbar.
209 * @param toolbar {qx.ui.toolbar.ToolBar} The application toolbar
210 */
211 createToolbarParts : function(toolbar){
212 toolbar.removeAll();
213 for(var key in this.toolbars){
214 var tPart = new qx.ui.toolbar.Part();
215 toolbar.add(tPart);
216 this.toolbars[key].map(function(command){
217 tPart.add(command.getToolbarButton());
218 });
219 }
220 },
221 /**
222 * Creates a context menu from an array of commands ids.
223 * @param commandIdsArray {Array} An array of string
224 * @return {qx.ui.menu.Menu}
225 */
226 createMenuFromIds : function(commandIdsArray){
227 var defs = this.getDefinitions();
228 var contextMenu = new qx.ui.menu.Menu();
229 for(var i=0;i<commandIdsArray.length;i++){
230 var definition = defs[commandIdsArray[i]];
231 if(definition){
232 var command = definition.command;
233 contextMenu.add(command.getMenuButton());
234 }
235 }
236 return contextMenu;
237 },
238 /**
239 * Add a new set of commands definitions
240 * @param definitions {Map} a set of commands definitions.
241 * @param callbackContext {qx.ui.core.Object} The context used inside the commands callbacks.
242 */
243 addCommands : function(definitions, callbackContext){
244 var crtDefs = this.getDefinitions();
245 for(var key in definitions){
246 if(callbackContext) definitions[key]['callbackContext'] = callbackContext;
247 crtDefs[key] = definitions[key];
248 }
249 this.setDefinitions(crtDefs);
250 this.fireEvent("changedCommands");
251 },
252 /**
253 * Removes a whole set of commands by their definitions maps.
254 * @param definitions {Map} a set of commands definitions
255 */
256 removeCommands : function(definitions){
257 var crtDefs = this.getDefinitions();
258 var initDefs = this.getInitialDefinitions();
259 for(var key in definitions){
260 if(!crtDefs[key]) continue;
261 if(initDefs[key]){
262 crtDefs[key] = initDefs[key];
263 }else{
264 delete crtDefs[key];
265 }
266 }
267 this.setDefinitions(crtDefs);
268 this.fireEvent("changedCommands");
269 },
270 /**
271 * Executes a command by its id.
272 * @param commandId {String} The command id.
273 */
274 executeCommand : function(commandId){
275 var defs = this.getDefinitions();
276 if(defs[commandId] && defs[commandId].command.getEnabled()){
277 defs[commandId].command.execute();
278 }
279 },
280 /**
281 * Retrieves a command by its id.
282 * @param commandId {String} The command id.
283 */
284 getCommandById : function(commandId){
285 var defs = this.getDefinitions();
286 if(defs[commandId] && defs[commandId].command){
287 return defs[commandId].command;
288 }
289 },
290 /**
291 * Add a standard context menu to a toolbar for button look and feel (show icon, text, both).
292 * @param toolbar {qx.ui.toolbar.ToolBar} The toolbar
293 */
294 addToolbarContextMenu : function(toolbar){
295 var menu = new qx.ui.menu.Menu();
296 var icon = new qx.ui.menu.RadioButton("Show Icons");
297 icon.setValue("icon");
298 var text = new qx.ui.menu.RadioButton("Show Text");
299 text.setValue("label");
300 var both = new qx.ui.menu.RadioButton("Show Both");
301 both.setValue("both");
302 var mgr = new qx.ui.form.RadioGroup(icon, text, both);
303 menu.add(icon);
304 menu.add(text);
305 menu.add(both);
306 toolbar.setContextMenu(menu);
307 mgr.addListener("changeValue", function(e){
308 this.setShow(e.getData());
309 }, toolbar);
310
311 }
312 }
313 });