PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-3-pre5/org/gjt/sp/jedit/gui/DockableWindowFactory.java

#
Java | 493 lines | 344 code | 63 blank | 86 comment | 25 complexity | 0b2e2b84c9cdce00c386dc46ad5482ce MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * DockableWindowFactory.java - loads dockables.xml, etc
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2005 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.gui;
  23. //{{{ Imports
  24. import bsh.*;
  25. import javax.swing.*;
  26. import java.awt.event.*;
  27. import java.awt.*;
  28. import java.io.*;
  29. import java.net.URL;
  30. import java.util.*;
  31. import org.xml.sax.Attributes;
  32. import org.xml.sax.InputSource;
  33. import org.xml.sax.helpers.DefaultHandler;
  34. import org.gjt.sp.jedit.msg.*;
  35. import org.gjt.sp.jedit.*;
  36. import org.gjt.sp.util.Log;
  37. //}}}
  38. /**
  39. * This class loads <code>dockable.xml</code> files and manages creation
  40. * of new dockable windows.
  41. *
  42. * @see DockableWindowManager
  43. *
  44. * @since jEdit 4.3pre2
  45. */
  46. public class DockableWindowFactory
  47. {
  48. //{{{ getInstance() method
  49. public static synchronized DockableWindowFactory getInstance()
  50. {
  51. if(instance == null)
  52. instance = new DockableWindowFactory();
  53. return instance;
  54. } //}}}
  55. //{{{ DockableWindowFactory constructor
  56. public DockableWindowFactory()
  57. {
  58. dockableWindowFactories = new HashMap();
  59. } //}}}
  60. //{{{ loadDockableWindows() method
  61. /**
  62. * Plugins shouldn't need to call this method.
  63. * @since jEdit 4.2pre1
  64. */
  65. public void loadDockableWindows(PluginJAR plugin, URL uri,
  66. PluginJAR.PluginCacheEntry cache)
  67. {
  68. try
  69. {
  70. Log.log(Log.DEBUG,DockableWindowManager.class,
  71. "Loading dockables from " + uri);
  72. DockableListHandler dh = new DockableListHandler(plugin,uri);
  73. boolean failure = MiscUtilities.parseXML(uri.openStream(), dh);
  74. if (!failure && cache != null)
  75. {
  76. cache.cachedDockableNames = dh.getCachedDockableNames();
  77. cache.cachedDockableActionFlags = dh.getCachedDockableActionFlags();
  78. }
  79. }
  80. catch(IOException e)
  81. {
  82. Log.log(Log.ERROR,DockableWindowManager.class,e);
  83. }
  84. } //}}}
  85. //{{{ unloadDockableWindows() method
  86. /**
  87. * Plugins shouldn't need to call this method.
  88. * @since jEdit 4.2pre1
  89. */
  90. public void unloadDockableWindows(PluginJAR plugin)
  91. {
  92. Iterator entries = dockableWindowFactories.entrySet().iterator();
  93. while(entries.hasNext())
  94. {
  95. Map.Entry entry = (Map.Entry)entries.next();
  96. Window factory = (Window)entry.getValue();
  97. if(factory.plugin == plugin)
  98. entries.remove();
  99. }
  100. } //}}}
  101. //{{{ cacheDockableWindows() method
  102. /**
  103. * @since jEdit 4.2pre1
  104. */
  105. public void cacheDockableWindows(PluginJAR plugin,
  106. String[] name, boolean[] actions)
  107. {
  108. for(int i = 0; i < name.length; i++)
  109. {
  110. Window factory = new Window(plugin,
  111. name[i],null,actions[i]);
  112. dockableWindowFactories.put(name[i],factory);
  113. }
  114. } //}}}
  115. //{{{ registerDockableWindow() method
  116. public void registerDockableWindow(PluginJAR plugin,
  117. String name, String code, boolean actions)
  118. {
  119. Window factory = (Window)dockableWindowFactories.get(name);
  120. if(factory != null)
  121. {
  122. factory.code = code;
  123. factory.loaded = true;
  124. }
  125. else
  126. {
  127. factory = new Window(plugin,name,code,actions);
  128. dockableWindowFactories.put(name,factory);
  129. }
  130. } //}}}
  131. //{{{ getRegisteredDockableWindows() method
  132. public String[] getRegisteredDockableWindows()
  133. {
  134. String[] retVal = new String[dockableWindowFactories.size()];
  135. Iterator entries = dockableWindowFactories.values().iterator();
  136. int i = 0;
  137. while(entries.hasNext())
  138. {
  139. Window factory = (Window)entries.next();
  140. retVal[i++] = factory.name;
  141. }
  142. return retVal;
  143. } //}}}
  144. //{{{ getDockableWindowIterator() method
  145. Iterator getDockableWindowIterator()
  146. {
  147. return dockableWindowFactories.values().iterator();
  148. } //}}}
  149. //{{{ DockableListHandler class
  150. class DockableListHandler extends DefaultHandler
  151. {
  152. //{{{ DockableListHandler constructor
  153. DockableListHandler(PluginJAR plugin, URL uri)
  154. {
  155. this.plugin = plugin;
  156. this.uri = uri;
  157. stateStack = new Stack();
  158. actions = true;
  159. code = new StringBuffer();
  160. cachedDockableNames = new LinkedList();
  161. cachedDockableActionFlags = new LinkedList();
  162. } //}}}
  163. //{{{ resolveEntity() method
  164. public InputSource resolveEntity(String publicId, String systemId)
  165. {
  166. return MiscUtilities.findEntity(systemId, "dockables.dtd", MiscUtilities.class);
  167. } //}}}
  168. //{{{ characters() method
  169. public void characters(char[] c, int off, int len)
  170. {
  171. String tag = peekElement();
  172. if (tag.equals("DOCKABLE"))
  173. code.append(c, off, len);
  174. } //}}}
  175. //{{{ startElement() method
  176. public void startElement(String uri, String localName,
  177. String qName, Attributes attrs)
  178. {
  179. String tag = pushElement(qName);
  180. if (tag.equals("DOCKABLE"))
  181. {
  182. dockableName = attrs.getValue("NAME");
  183. actions = "FALSE".equals(attrs.getValue("NO_ACTIONS"));
  184. }
  185. } //}}}
  186. //{{{ endElement() method
  187. public void endElement(String uri, String localName, String name)
  188. {
  189. if(name == null)
  190. return;
  191. String tag = peekElement();
  192. if(name.equals(tag))
  193. {
  194. if(tag.equals("DOCKABLE"))
  195. {
  196. registerDockableWindow(plugin,
  197. dockableName,code.toString(),actions);
  198. cachedDockableNames.add(dockableName);
  199. cachedDockableActionFlags.add(
  200. new Boolean(actions));
  201. // make default be true for the next
  202. // action
  203. actions = true;
  204. code.setLength(0);
  205. }
  206. popElement();
  207. }
  208. else
  209. {
  210. // can't happen
  211. throw new InternalError();
  212. }
  213. } //}}}
  214. //{{{ startDocument() method
  215. public void startDocument()
  216. {
  217. try
  218. {
  219. pushElement(null);
  220. }
  221. catch (Exception e)
  222. {
  223. e.printStackTrace();
  224. }
  225. } //}}}
  226. //{{{ getCachedDockableNames() method
  227. public String[] getCachedDockableNames()
  228. {
  229. return (String[])cachedDockableNames.toArray(new String[cachedDockableNames.size()]);
  230. } //}}}
  231. //{{{ getCachedDockableActionFlags() method
  232. public boolean[] getCachedDockableActionFlags()
  233. {
  234. boolean[] returnValue = new boolean[
  235. cachedDockableActionFlags.size()];
  236. Iterator iter = cachedDockableActionFlags.iterator();
  237. int i = 0;
  238. while(iter.hasNext())
  239. {
  240. boolean flag = ((Boolean)iter.next())
  241. .booleanValue();
  242. returnValue[i++] = flag;
  243. }
  244. return returnValue;
  245. } //}}}
  246. //{{{ Private members
  247. //{{{ Instance variables
  248. private PluginJAR plugin;
  249. private URL uri;
  250. private java.util.List cachedDockableNames;
  251. private java.util.List cachedDockableActionFlags;
  252. private String dockableName;
  253. private StringBuffer code;
  254. private boolean actions;
  255. private Stack stateStack;
  256. //}}}
  257. //{{{ pushElement() method
  258. private String pushElement(String name)
  259. {
  260. name = (name == null) ? null : name.intern();
  261. stateStack.push(name);
  262. return name;
  263. } //}}}
  264. //{{{ peekElement() method
  265. private String peekElement()
  266. {
  267. return (String) stateStack.peek();
  268. } //}}}
  269. //{{{ popElement() method
  270. private String popElement()
  271. {
  272. return (String) stateStack.pop();
  273. } //}}}
  274. //}}}
  275. } //}}}
  276. //{{{ Window class
  277. class Window
  278. {
  279. PluginJAR plugin;
  280. String name;
  281. String code;
  282. boolean loaded;
  283. //{{{ Window constructor
  284. Window(PluginJAR plugin, String name, String code,
  285. boolean actions)
  286. {
  287. this.plugin = plugin;
  288. this.name = name;
  289. this.code = code;
  290. if(code != null)
  291. loaded = true;
  292. if(actions)
  293. {
  294. ActionSet actionSet = (plugin == null
  295. ? jEdit.getBuiltInActionSet()
  296. : plugin.getActionSet());
  297. actionSet.addAction(new OpenAction(name));
  298. actionSet.addAction(new ToggleAction(name));
  299. actionSet.addAction(new FloatAction(name));
  300. String label = jEdit.getProperty(name
  301. + ".label");
  302. if(label == null)
  303. label = "NO LABEL PROPERTY: " + name;
  304. String[] args = { label };
  305. jEdit.setTemporaryProperty(name + ".label",
  306. label);
  307. jEdit.setTemporaryProperty(name
  308. + "-toggle.label",
  309. jEdit.getProperty(
  310. "view.docking.toggle.label",args));
  311. jEdit.setTemporaryProperty(name
  312. + "-toggle.toggle","true");
  313. jEdit.setTemporaryProperty(name
  314. + "-float.label",
  315. jEdit.getProperty(
  316. "view.docking.float.label",args));
  317. }
  318. } //}}}
  319. //{{{ load() method
  320. void load()
  321. {
  322. if(loaded)
  323. return;
  324. loadDockableWindows(plugin,plugin.getDockablesURI(),null);
  325. } //}}}
  326. //{{{ createDockableWindow() method
  327. JComponent createDockableWindow(View view, String position)
  328. {
  329. load();
  330. if(!loaded)
  331. {
  332. Log.log(Log.WARNING,this,"Outdated cache");
  333. return null;
  334. }
  335. NameSpace nameSpace = new NameSpace(
  336. BeanShell.getNameSpace(),
  337. "DockableWindowManager.Factory"
  338. + ".createDockableWindow()");
  339. try
  340. {
  341. nameSpace.setVariable(
  342. "position",position);
  343. }
  344. catch(UtilEvalError e)
  345. {
  346. Log.log(Log.ERROR,this,e);
  347. }
  348. JComponent win = (JComponent)BeanShell.eval(view,
  349. nameSpace,code);
  350. return win;
  351. } //}}}
  352. //{{{ OpenAction class
  353. class OpenAction extends EditAction
  354. {
  355. private String dockable;
  356. //{{{ OpenAction constructor
  357. OpenAction(String name)
  358. {
  359. super(name);
  360. this.dockable = name;
  361. } //}}}
  362. //{{{ invoke() method
  363. public void invoke(View view)
  364. {
  365. view.getDockableWindowManager()
  366. .showDockableWindow(dockable);
  367. } //}}}
  368. //{{{ getCode() method
  369. public String getCode()
  370. {
  371. return "view.getDockableWindowManager()"
  372. + ".showDockableWindow(\"" + dockable + "\");";
  373. } //}}}
  374. } //}}}
  375. //{{{ ToggleAction class
  376. class ToggleAction extends EditAction
  377. {
  378. private String dockable;
  379. //{{{ ToggleAction constructor
  380. ToggleAction(String name)
  381. {
  382. super(name + "-toggle");
  383. this.dockable = name;
  384. } //}}}
  385. //{{{ invoke() method
  386. public void invoke(View view)
  387. {
  388. view.getDockableWindowManager()
  389. .toggleDockableWindow(dockable);
  390. } //}}}
  391. //{{{ isSelected() method
  392. public boolean isSelected(View view)
  393. {
  394. return view.getDockableWindowManager()
  395. .isDockableWindowVisible(dockable);
  396. } //}}}
  397. //{{{ getCode() method
  398. public String getCode()
  399. {
  400. return "view.getDockableWindowManager()"
  401. + ".toggleDockableWindow(\"" + dockable + "\");";
  402. } //}}}
  403. } //}}}
  404. //{{{ FloatAction class
  405. class FloatAction extends EditAction
  406. {
  407. private String dockable;
  408. //{{{ FloatAction constructor
  409. FloatAction(String name)
  410. {
  411. super(name + "-float");
  412. this.dockable = name;
  413. } //}}}
  414. //{{{ invoke() method
  415. public void invoke(View view)
  416. {
  417. view.getDockableWindowManager()
  418. .floatDockableWindow(dockable);
  419. } //}}}
  420. //{{{ getCode() method
  421. public String getCode()
  422. {
  423. return "view.getDockableWindowManager()"
  424. + ".floatDockableWindow(\"" + dockable + "\");";
  425. } //}}}
  426. } //}}}
  427. } //}}}
  428. private static DockableWindowFactory instance;
  429. private HashMap dockableWindowFactories;
  430. }