OSDN Git Service

import source-tree based svn r84.
[bluegriffon/BlueGriffon.git] / base / content / bluegriffon / js / commands.js
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is BlueGriffon.
15  *
16  * The Initial Developer of the Original Code is
17  * Disruptive Innovations SARL.
18  * Portions created by the Initial Developer are Copyright (C) 2006
19  * the Initial Developer. All Rights Reserved.
20  *
21  * Contributor(s):
22  *   Daniel Glazman <daniel.glazman@disruptive-innovations.com>, Original author
23  *
24  * Alternatively, the contents of this file may be used under the terms of
25  * either the GNU General Public License Version 2 or later (the "GPL"), or
26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27  * in which case the provisions of the GPL or the LGPL are applicable instead
28  * of those above. If you wish to allow use of your version of this file only
29  * under the terms of either the GPL or the LGPL, and not to allow others to
30  * use your version of this file under the terms of the MPL, indicate your
31  * decision by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL or the LGPL. If you do not delete
33  * the provisions above, a recipient may use your version of this file under
34  * the terms of any one of the MPL, the GPL or the LGPL.
35  *
36  * ***** END LICENSE BLOCK ***** */
37
38 const kBASE_COMMAND_CONTROLLER_CID = "@mozilla.org/embedcomp/base-command-controller;1";
39
40 const nsIControllerContext = interfaces.nsIControllerContext;
41 const nsIInterfaceRequestor = interfaces.nsIInterfaceRequestor;
42 const nsIControllerCommandTable = interfaces.nsIControllerCommandTable;
43
44 var ComposerCommands = {
45
46   mComposerJSCommandControllerID: null,
47   mSelectionTimeOutId: null,
48
49   getComposerCommandTable: function getComposerCommandTable()
50   {
51     var controller;
52     if (this.mComposerJSCommandControllerID)
53     {
54       try { 
55         controller = window.content.controllers.getControllerById(this.mComposerJSCommandControllerID);
56       } catch (e) {}
57     }
58     if (!controller)
59     {
60       //create it
61       controller = Components.classes[kBASE_COMMAND_CONTROLLER_CID].createInstance();
62   
63       var editorController = controller.QueryInterface(nsIControllerContext);
64       editorController.init(null);
65       editorController.setCommandContext(null);
66       window.controllers.insertControllerAt(0, controller);
67     
68       // Store the controller ID so we can be sure to get the right one later
69       this.mComposerJSCommandControllerID = window.controllers.getControllerId(controller);
70     }
71   
72     if (controller)
73     {
74       var interfaceRequestor = controller.QueryInterface(nsIInterfaceRequestor);
75       return interfaceRequestor.getInterface(nsIControllerCommandTable);
76     }
77     return null;
78   },
79
80   goUpdateComposerMenuItems: function goUpdateComposerMenuItems(commandset)
81   {
82     dump("Updating commands for " + commandset.id + "\n");
83     for (var i = 0; i < commandset.childNodes.length; i++)
84     {
85       var commandNode = commandset.childNodes[i];
86       var commandID = commandNode.id;
87       if (commandID)
88       {
89         goUpdateCommand(commandID);  // enable or disable
90         if (commandNode.hasAttribute("state"))
91           this.goUpdateCommandState(commandID);
92       }
93     }
94   },
95
96   goUpdateCommandState: function goUpdateCommandState(command)
97   {
98     try
99     {
100       var controller = top.document.commandDispatcher.getControllerForCommand(command);
101       if (!(controller instanceof Components.interfaces.nsICommandController))
102         return;
103
104       var params = this.newCommandParams();
105       if (!params) return;
106
107       controller.getCommandStateWithParams(command, params);
108
109       switch (command)
110       {
111         case "cmd_bold":
112         case "cmd_italic":
113         case "cmd_underline":
114         case "cmd_strong":
115         case "cmd_em":
116         case "cmd_code":
117
118         case "cmd_ul":
119         case "cmd_ol":
120
121         case "cmd_dd":
122         case "cmd_dt":
123           this.pokeStyleUI(command, params.getBooleanValue("state_all"));
124           break;
125
126         case "cmd_paragraphState":
127         case "cmd_align":
128         case "cmd_fontFace":
129         case "cmd_class":
130           this.pokeMultiStateUI(command, params);
131           break;
132
133         case "cmd_indent":
134         case "cmd_outdent":
135           break;
136
137         default: dump("no update for command: " +command+"\n");
138       }
139     }
140     catch (e) { dump("An error occurred updating the "+command+" command: \n"+e+"\n"); }
141   },
142
143   pokeStyleUI: function pokeStyleUI(uiID, aDesiredState)
144   {
145    try {
146     var commandNode = top.document.getElementById(uiID);
147     if (!commandNode)
148       return;
149
150     var uiState = ("true" == commandNode.getAttribute("state"));
151     if (aDesiredState != uiState)
152     {
153       var newState;
154       if (aDesiredState)
155         newState = "true";
156       else
157         newState = "false";
158       commandNode.setAttribute("state", newState);
159     }
160    } catch(e) { dump("poking UI for "+uiID+" failed: "+e+"\n"); }
161   },
162
163   newCommandParams: function newCommandParams()
164   {
165     try {
166       return Components.classes["@mozilla.org/embedcomp/command-params;1"].createInstance(Components.interfaces.nsICommandParams);
167     }
168     catch(e) { dump("error thrown in newCommandParams: "+e+"\n"); }
169     return null;
170   },
171
172   pokeMultiStateUI: function pokeMultiStateUI(uiID, cmdParams)
173   {
174     try
175     {
176       var commandNode = document.getElementById(uiID);
177       if (!commandNode)
178         return;
179
180       var isMixed = cmdParams.getBooleanValue("state_mixed");
181       var desiredAttrib;
182       if (isMixed)
183         desiredAttrib = "mixed";
184       else
185         desiredAttrib = cmdParams.getCStringValue("state_attribute");
186
187       var uiState = commandNode.getAttribute("state");
188       if (desiredAttrib != uiState)
189       {
190         commandNode.setAttribute("state", desiredAttrib);
191       }
192     } catch(e) {}
193   },
194
195   doStyleUICommand: function doStyleUICommand(cmdStr)
196   {
197     try
198     {
199       var cmdParams = this.newCommandParams();
200       this.goDoCommandParams(cmdStr, cmdParams);
201     } catch(e) {}
202   },
203
204   doStatefulCommand: function doStatefulCommand(commandID, newState)
205   {
206     var commandNode = document.getElementById(commandID);
207     if (commandNode)
208         commandNode.setAttribute("state", newState);
209
210     try
211     {
212       var cmdParams = this.newCommandParams();
213       if (!cmdParams) return;
214
215       cmdParams.setCStringValue("state_attribute", newState);
216       this.goDoCommandParams(commandID, cmdParams);
217
218       this.pokeMultiStateUI(commandID, cmdParams);
219
220     } catch(e) { dump("error thrown in doStatefulCommand: "+e+"\n"); }
221   },
222
223   goDoCommandParams: function goDoCommandParams(command, params)
224   {
225     try
226     {
227       var controller = top.document.commandDispatcher.getControllerForCommand(command);
228       if (controller && controller.isCommandEnabled(command))
229       {
230         if (controller instanceof Components.interfaces.nsICommandController)
231         {
232           controller.doCommandWithParams(command, params);
233
234           // the following two lines should be removed when we implement observers
235           if (params)
236             controller.getCommandStateWithParams(command, params);
237         }
238         else
239         {
240           controller.doCommand(command);
241         }
242       }
243     }
244     catch (e)
245     {
246       dump("An error occurred executing the "+command+" command\n");
247     }
248   },
249
250   setupMainCommands: function setupMainCommands()
251   {
252     var commandTable = this.getComposerCommandTable();
253     if (!commandTable)
254       return;
255     
256     //dump("Registering plain text editor commands\n");
257     commandTable.registerCommand("cmd_stopLoading", cmdStopLoading);
258     commandTable.registerCommand("cmd_open",        cmdOpen);
259     commandTable.registerCommand("cmd_save",        cmdSave);
260     commandTable.registerCommand("cmd_saveAs",      cmdSaveAs);
261     commandTable.registerCommand("cmd_fullScreen",  cmdFullScreen);
262     commandTable.registerCommand("cmd_new",         cmdNew);
263     commandTable.registerCommand("cmd_newWizard",   cmdNewWizard);
264     commandTable.registerCommand("cmd_renderedHTMLEnabler", cmdDummyHTML);
265     commandTable.registerCommand("cmd_cleanup",     cmdMarkupCleaner);
266
267     commandTable.registerCommand("cmd_table",       cmdInsertOrEditTableCommand);
268
269     commandTable.registerCommand("cmd_class", cmdClass);
270   },
271
272   setupFormatCommands: function setupFormatCommands()
273   {
274     try {
275       var commandManager = EditorUtils.getCurrentCommandManager();
276
277       commandManager.addCommandObserver(gEditorDocumentObserver, "obs_documentCreated");
278       commandManager.addCommandObserver(gEditorDocumentObserver, "cmd_setDocumentModified");
279       commandManager.addCommandObserver(gEditorDocumentObserver, "obs_documentWillBeDestroyed");
280       commandManager.addCommandObserver(gEditorDocumentObserver, "obs_documentLocationChanged");
281
282       // cmd_bold is a proxy, that's the only style command we add here
283       commandManager.addCommandObserver(gEditorDocumentObserver, "cmd_bold");
284     } catch (e) { alert(e); }
285   },
286
287   updateSelectionBased: function updateSelectionBased(aElt, aEvent)
288   {
289     try {
290       var mixed = EditorUtils.getSelectionContainer();
291       if (!mixed) return;
292       var element = mixed.node;
293       var oneElementSelected = mixed.oneElementSelected;
294
295       if (!element) return;
296
297       if (this.mSelectionTimeOutId)
298         clearTimeout(this.mSelectionTimeOutId);
299
300       this.mSelectionTimeOutId = setTimeout(this._updateSelectionBased, 100, element, oneElementSelected);
301     }
302     catch(e) {}
303   },
304
305   _updateSelectionBased: function _updateSelectionBased(aElement, aOneElementSelected)
306   {
307     NotifierUtils.notify("selection", aElement, aOneElementSelected);
308   },
309
310   onStateButtonUpdate: function onStateButtonUpdate(button, commmandID, onState)
311   {
312     var commandNode = document.getElementById(commmandID);
313     var state = commandNode.getAttribute("state");
314   
315     button.checked = state == onState;
316   },
317
318   selectionListener: {
319     notifySelectionChanged: function(doc, sel, reason)
320     {
321       ComposerCommands.updateSelectionBased();
322     }
323
324   }
325 };
326
327 #include navigationCommands.inc
328 #include fileCommands.inc
329 #include viewCommands.inc
330 #include dummyCommands.inc
331 #include formatCommands.inc
332 #include insertionCommands.inc
333