PageRenderTime 128ms CodeModel.GetById 70ms app.highlight 30ms RepoModel.GetById 20ms 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
  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
 23package org.gjt.sp.jedit.gui;
 24
 25//{{{ Imports
 26import bsh.*;
 27import javax.swing.*;
 28import java.awt.event.*;
 29import java.awt.*;
 30import java.io.*;
 31import java.net.URL;
 32import java.util.*;
 33
 34import org.xml.sax.Attributes;
 35import org.xml.sax.InputSource;
 36import org.xml.sax.helpers.DefaultHandler;
 37
 38import org.gjt.sp.jedit.msg.*;
 39import org.gjt.sp.jedit.*;
 40import org.gjt.sp.util.Log;
 41//}}}
 42
 43/**
 44 * This class loads <code>dockable.xml</code> files and manages creation
 45 * of new dockable windows.
 46 *
 47 * @see DockableWindowManager
 48 *
 49 * @since jEdit 4.3pre2
 50 */
 51public class DockableWindowFactory
 52{
 53	//{{{ getInstance() method
 54	public static synchronized DockableWindowFactory getInstance()
 55	{
 56		if(instance == null)
 57			instance = new DockableWindowFactory();
 58		return instance;
 59	} //}}}
 60
 61	//{{{ DockableWindowFactory constructor
 62	public DockableWindowFactory()
 63	{
 64		dockableWindowFactories = new HashMap();
 65	} //}}}
 66
 67	//{{{ loadDockableWindows() method
 68	/**
 69	 * Plugins shouldn't need to call this method.
 70	 * @since jEdit 4.2pre1
 71	 */
 72	public void loadDockableWindows(PluginJAR plugin, URL uri,
 73		PluginJAR.PluginCacheEntry cache)
 74	{
 75		try
 76		{
 77			Log.log(Log.DEBUG,DockableWindowManager.class,
 78				"Loading dockables from " + uri);
 79			DockableListHandler dh = new DockableListHandler(plugin,uri);
 80			boolean failure = MiscUtilities.parseXML(uri.openStream(), dh);
 81
 82			if (!failure && cache != null)
 83			{
 84				cache.cachedDockableNames = dh.getCachedDockableNames();
 85				cache.cachedDockableActionFlags = dh.getCachedDockableActionFlags();
 86			}
 87		}
 88		catch(IOException e)
 89		{
 90			Log.log(Log.ERROR,DockableWindowManager.class,e);
 91		}
 92	} //}}}
 93
 94	//{{{ unloadDockableWindows() method
 95	/**
 96	 * Plugins shouldn't need to call this method.
 97	 * @since jEdit 4.2pre1
 98	 */
 99	public void unloadDockableWindows(PluginJAR plugin)
100	{
101		Iterator entries = dockableWindowFactories.entrySet().iterator();
102		while(entries.hasNext())
103		{
104			Map.Entry entry = (Map.Entry)entries.next();
105			Window factory = (Window)entry.getValue();
106			if(factory.plugin == plugin)
107				entries.remove();
108		}
109	} //}}}
110
111	//{{{ cacheDockableWindows() method
112	/**
113	 * @since jEdit 4.2pre1
114	 */
115	public void cacheDockableWindows(PluginJAR plugin,
116		String[] name, boolean[] actions)
117	{
118		for(int i = 0; i < name.length; i++)
119		{
120			Window factory = new Window(plugin,
121				name[i],null,actions[i]);
122			dockableWindowFactories.put(name[i],factory);
123		}
124	} //}}}
125
126	//{{{ registerDockableWindow() method
127	public void registerDockableWindow(PluginJAR plugin,
128		String name, String code, boolean actions)
129	{
130		Window factory = (Window)dockableWindowFactories.get(name);
131		if(factory != null)
132		{
133			factory.code = code;
134			factory.loaded = true;
135		}
136		else
137		{
138			factory = new Window(plugin,name,code,actions);
139			dockableWindowFactories.put(name,factory);
140		}
141	} //}}}
142
143	//{{{ getRegisteredDockableWindows() method
144	public String[] getRegisteredDockableWindows()
145	{
146		String[] retVal = new String[dockableWindowFactories.size()];
147		Iterator entries = dockableWindowFactories.values().iterator();
148		int i = 0;
149		while(entries.hasNext())
150		{
151			Window factory = (Window)entries.next();
152			retVal[i++] = factory.name;
153		}
154
155		return retVal;
156	} //}}}
157
158	//{{{ getDockableWindowIterator() method
159	Iterator getDockableWindowIterator()
160	{
161		return dockableWindowFactories.values().iterator();
162	} //}}}
163
164	//{{{ DockableListHandler class
165	class DockableListHandler extends DefaultHandler
166	{
167		//{{{ DockableListHandler constructor
168		DockableListHandler(PluginJAR plugin, URL uri)
169		{
170			this.plugin = plugin;
171			this.uri = uri;
172			stateStack = new Stack();
173			actions = true;
174
175			code = new StringBuffer();
176			cachedDockableNames = new LinkedList();
177			cachedDockableActionFlags = new LinkedList();
178		} //}}}
179
180		//{{{ resolveEntity() method
181		public InputSource resolveEntity(String publicId, String systemId)
182		{
183			return MiscUtilities.findEntity(systemId, "dockables.dtd", MiscUtilities.class);
184		} //}}}
185
186		//{{{ characters() method
187		public void characters(char[] c, int off, int len)
188		{
189			String tag = peekElement();
190			if (tag.equals("DOCKABLE"))
191				code.append(c, off, len);
192		} //}}}
193
194		//{{{ startElement() method
195		public void startElement(String uri, String localName,
196					 String qName, Attributes attrs)
197		{
198			String tag = pushElement(qName);
199			if (tag.equals("DOCKABLE"))
200			{
201				dockableName = attrs.getValue("NAME");
202				actions = "FALSE".equals(attrs.getValue("NO_ACTIONS"));
203			}
204		} //}}}
205
206		//{{{ endElement() method
207		public void endElement(String uri, String localName, String name)
208		{
209			if(name == null)
210				return;
211
212			String tag = peekElement();
213
214			if(name.equals(tag))
215			{
216				if(tag.equals("DOCKABLE"))
217				{
218					registerDockableWindow(plugin,
219						dockableName,code.toString(),actions);
220					cachedDockableNames.add(dockableName);
221					cachedDockableActionFlags.add(
222						new Boolean(actions));
223					// make default be true for the next
224					// action
225					actions = true;
226					code.setLength(0);
227				}
228
229				popElement();
230			}
231			else
232			{
233				// can't happen
234				throw new InternalError();
235			}
236		} //}}}
237
238		//{{{ startDocument() method
239		public void startDocument()
240		{
241			try
242			{
243				pushElement(null);
244			}
245			catch (Exception e)
246			{
247				e.printStackTrace();
248			}
249		} //}}}
250
251		//{{{ getCachedDockableNames() method
252		public String[] getCachedDockableNames()
253		{
254			return (String[])cachedDockableNames.toArray(new String[cachedDockableNames.size()]);
255		} //}}}
256
257		//{{{ getCachedDockableActionFlags() method
258		public boolean[] getCachedDockableActionFlags()
259		{
260			boolean[] returnValue = new boolean[
261				cachedDockableActionFlags.size()];
262			Iterator iter = cachedDockableActionFlags.iterator();
263			int i = 0;
264			while(iter.hasNext())
265			{
266				boolean flag = ((Boolean)iter.next())
267					.booleanValue();
268				returnValue[i++] = flag;
269			}
270
271			return returnValue;
272		} //}}}
273
274		//{{{ Private members
275
276		//{{{ Instance variables
277		private PluginJAR plugin;
278		private URL uri;
279
280		private java.util.List cachedDockableNames;
281		private java.util.List cachedDockableActionFlags;
282
283		private String dockableName;
284		private StringBuffer code;
285		private boolean actions;
286
287		private Stack stateStack;
288		//}}}
289
290		//{{{ pushElement() method
291		private String pushElement(String name)
292		{
293			name = (name == null) ? null : name.intern();
294
295			stateStack.push(name);
296
297			return name;
298		} //}}}
299
300		//{{{ peekElement() method
301		private String peekElement()
302		{
303			return (String) stateStack.peek();
304		} //}}}
305
306		//{{{ popElement() method
307		private String popElement()
308		{
309			return (String) stateStack.pop();
310		} //}}}
311
312		//}}}
313	} //}}}
314
315	//{{{ Window class
316	class Window
317	{
318		PluginJAR plugin;
319		String name;
320		String code;
321		boolean loaded;
322
323		//{{{ Window constructor
324		Window(PluginJAR plugin, String name, String code,
325			boolean actions)
326		{
327			this.plugin = plugin;
328			this.name = name;
329			this.code = code;
330
331			if(code != null)
332				loaded = true;
333
334			if(actions)
335			{
336				ActionSet actionSet = (plugin == null
337					? jEdit.getBuiltInActionSet()
338					: plugin.getActionSet());
339				actionSet.addAction(new OpenAction(name));
340				actionSet.addAction(new ToggleAction(name));
341				actionSet.addAction(new FloatAction(name));
342
343				String label = jEdit.getProperty(name
344					+ ".label");
345				if(label == null)
346					label = "NO LABEL PROPERTY: " + name;
347
348				String[] args = { label };
349				jEdit.setTemporaryProperty(name + ".label",
350					label);
351				jEdit.setTemporaryProperty(name
352					+ "-toggle.label",
353					jEdit.getProperty(
354					"view.docking.toggle.label",args));
355				jEdit.setTemporaryProperty(name
356					+ "-toggle.toggle","true");
357				jEdit.setTemporaryProperty(name
358					+ "-float.label",
359					jEdit.getProperty(
360					"view.docking.float.label",args));
361			}
362		} //}}}
363
364		//{{{ load() method
365		void load()
366		{
367			if(loaded)
368				return;
369
370			loadDockableWindows(plugin,plugin.getDockablesURI(),null);
371		} //}}}
372
373		//{{{ createDockableWindow() method
374		JComponent createDockableWindow(View view, String position)
375		{
376			load();
377
378			if(!loaded)
379			{
380				Log.log(Log.WARNING,this,"Outdated cache");
381				return null;
382			}
383
384			NameSpace nameSpace = new NameSpace(
385				BeanShell.getNameSpace(),
386				"DockableWindowManager.Factory"
387				+ ".createDockableWindow()");
388			try
389			{
390				nameSpace.setVariable(
391					"position",position);
392			}
393			catch(UtilEvalError e)
394			{
395				Log.log(Log.ERROR,this,e);
396			}
397			JComponent win = (JComponent)BeanShell.eval(view,
398				nameSpace,code);
399			return win;
400		} //}}}
401
402		//{{{ OpenAction class
403		class OpenAction extends EditAction
404		{
405			private String dockable;
406
407			//{{{ OpenAction constructor
408			OpenAction(String name)
409			{
410				super(name);
411				this.dockable = name;
412			} //}}}
413
414			//{{{ invoke() method
415			public void invoke(View view)
416			{
417				view.getDockableWindowManager()
418					.showDockableWindow(dockable);
419			} //}}}
420
421			//{{{ getCode() method
422			public String getCode()
423			{
424				return "view.getDockableWindowManager()"
425					+ ".showDockableWindow(\"" + dockable + "\");";
426			} //}}}
427		} //}}}
428
429		//{{{ ToggleAction class
430		class ToggleAction extends EditAction
431		{
432			private String dockable;
433
434			//{{{ ToggleAction constructor
435			ToggleAction(String name)
436			{
437				super(name + "-toggle");
438				this.dockable = name;
439			} //}}}
440
441			//{{{ invoke() method
442			public void invoke(View view)
443			{
444				view.getDockableWindowManager()
445					.toggleDockableWindow(dockable);
446			} //}}}
447
448			//{{{ isSelected() method
449			public boolean isSelected(View view)
450			{
451				return view.getDockableWindowManager()
452					.isDockableWindowVisible(dockable);
453			} //}}}
454
455			//{{{ getCode() method
456			public String getCode()
457			{
458				return "view.getDockableWindowManager()"
459					+ ".toggleDockableWindow(\"" + dockable + "\");";
460			} //}}}
461		} //}}}
462
463		//{{{ FloatAction class
464		class FloatAction extends EditAction
465		{
466			private String dockable;
467
468			//{{{ FloatAction constructor
469			FloatAction(String name)
470			{
471				super(name + "-float");
472				this.dockable = name;
473			} //}}}
474
475			//{{{ invoke() method
476			public void invoke(View view)
477			{
478				view.getDockableWindowManager()
479					.floatDockableWindow(dockable);
480			} //}}}
481
482			//{{{ getCode() method
483			public String getCode()
484			{
485				return "view.getDockableWindowManager()"
486					+ ".floatDockableWindow(\"" + dockable + "\");";
487			} //}}}
488		} //}}}
489	} //}}}
490
491	private static DockableWindowFactory instance;
492	private HashMap dockableWindowFactories;
493}