1 22 23 package org.gjt.sp.jedit.gui; 24 25 import java.io.IOException ; 27 import java.net.URL ; 28 import java.util.HashMap ; 29 import java.util.Iterator ; 30 import java.util.LinkedList ; 31 import java.util.Map ; 32 import java.util.Stack ; 33 34 import javax.swing.JComponent ; 35 36 import org.gjt.sp.jedit.ActionSet; 37 import org.gjt.sp.jedit.BeanShell; 38 import org.gjt.sp.jedit.EditAction; 39 import org.gjt.sp.jedit.MiscUtilities; 40 import org.gjt.sp.jedit.PluginJAR; 41 import org.gjt.sp.jedit.View; 42 import org.gjt.sp.jedit.jEdit; 43 import org.gjt.sp.util.Log; 44 import org.gjt.sp.util.XMLUtilities; 45 import org.xml.sax.Attributes ; 46 import org.xml.sax.InputSource ; 47 import org.xml.sax.helpers.DefaultHandler ; 48 49 import bsh.NameSpace; 50 import bsh.UtilEvalError; 51 53 61 public class DockableWindowFactory 62 { 63 public static synchronized DockableWindowFactory getInstance() 65 { 66 if(instance == null) 67 instance = new DockableWindowFactory(); 68 return instance; 69 } 71 public DockableWindowFactory() 73 { 74 dockableWindowFactories = new HashMap <String , Window>(); 75 } 77 82 public void loadDockableWindows(PluginJAR plugin, URL uri, 83 PluginJAR.PluginCacheEntry cache) 84 { 85 try 86 { 87 Log.log(Log.DEBUG,DockableWindowManager.class, 88 "Loading dockables from " + uri); 89 DockableListHandler dh = new DockableListHandler(plugin,uri); 90 boolean failure = XMLUtilities.parseXML(uri.openStream(), dh); 91 92 if (!failure && cache != null) 93 { 94 cache.cachedDockableNames = dh.getCachedDockableNames(); 95 cache.cachedDockableActionFlags = dh.getCachedDockableActionFlags(); 96 } 97 } 98 catch(IOException e) 99 { 100 Log.log(Log.ERROR,DockableWindowManager.class,e); 101 } 102 } 104 109 public void unloadDockableWindows(PluginJAR plugin) 110 { 111 Iterator entries = dockableWindowFactories.entrySet().iterator(); 112 while(entries.hasNext()) 113 { 114 Map.Entry entry = (Map.Entry )entries.next(); 115 Window factory = (Window)entry.getValue(); 116 if(factory.plugin == plugin) 117 entries.remove(); 118 } 119 } 121 125 public void cacheDockableWindows(PluginJAR plugin, 126 String [] name, boolean[] actions) 127 { 128 for(int i = 0; i < name.length; i++) 129 { 130 Window factory = new Window(plugin, 131 name[i],null,actions[i]); 132 dockableWindowFactories.put(name[i],factory); 133 } 134 } 136 public void registerDockableWindow(PluginJAR plugin, 138 String name, String code, boolean actions) 139 { 140 Window factory = dockableWindowFactories.get(name); 141 if(factory != null) 142 { 143 factory.code = code; 144 factory.loaded = true; 145 } 146 else 147 { 148 factory = new Window(plugin,name,code,actions); 149 dockableWindowFactories.put(name,factory); 150 } 151 } 153 public String [] getRegisteredDockableWindows() 155 { 156 String [] retVal = new String [dockableWindowFactories.size()]; 157 Iterator <Window> entries = dockableWindowFactories.values().iterator(); 158 int i = 0; 159 while(entries.hasNext()) 160 { 161 Window factory = entries.next(); 162 retVal[i++] = factory.name; 163 } 164 165 return retVal; 166 } 168 Iterator <Window> getDockableWindowIterator() 170 { 171 return dockableWindowFactories.values().iterator(); 172 } 174 class DockableListHandler extends DefaultHandler 176 { 177 182 DockableListHandler(PluginJAR plugin, URL uri) 183 { 184 this.plugin = plugin; 185 this.uri = uri; 186 stateStack = new Stack (); 187 actions = true; 188 189 code = new StringBuffer (); 190 cachedDockableNames = new LinkedList <String >(); 191 cachedDockableActionFlags = new LinkedList (); 192 } 194 public InputSource resolveEntity(String publicId, String systemId) 196 { 197 return XMLUtilities.findEntity(systemId, "dockables.dtd", MiscUtilities.class); 198 } 200 public void characters(char[] c, int off, int len) 202 { 203 String tag = peekElement(); 204 if (tag.equals("DOCKABLE")) 205 code.append(c, off, len); 206 } 208 public void startElement(String uri, String localName, 210 String qName, Attributes attrs) 211 { 212 String tag = pushElement(qName); 213 if (tag.equals("DOCKABLE")) 214 { 215 dockableName = attrs.getValue("NAME"); 216 actions = "FALSE".equals(attrs.getValue("NO_ACTIONS")); 217 } 218 } 220 public void endElement(String uri, String localName, String name) 222 { 223 if(name == null) 224 return; 225 226 String tag = peekElement(); 227 228 if(name.equals(tag)) 229 { 230 if(tag.equals("DOCKABLE")) 231 { 232 registerDockableWindow(plugin, 233 dockableName,code.toString(),actions); 234 cachedDockableNames.add(dockableName); 235 cachedDockableActionFlags.add( 236 new Boolean (actions)); 237 actions = true; 240 code.setLength(0); 241 } 242 243 popElement(); 244 } 245 else 246 { 247 throw new InternalError (); 249 } 250 } 252 public void startDocument() 254 { 255 try 256 { 257 pushElement(null); 258 } 259 catch (Exception e) 260 { 261 e.printStackTrace(); 262 } 263 } 265 public String [] getCachedDockableNames() 267 { 268 return (String [])cachedDockableNames.toArray(new String [cachedDockableNames.size()]); 269 } 271 public boolean[] getCachedDockableActionFlags() 273 { 274 boolean[] returnValue = new boolean[ 275 cachedDockableActionFlags.size()]; 276 Iterator iter = cachedDockableActionFlags.iterator(); 277 int i = 0; 278 while(iter.hasNext()) 279 { 280 boolean flag = ((Boolean )iter.next()) 281 .booleanValue(); 282 returnValue[i++] = flag; 283 } 284 285 return returnValue; 286 } 288 290 private PluginJAR plugin; 292 private URL uri; 294 295 private java.util.List <String > cachedDockableNames; 296 private java.util.List cachedDockableActionFlags; 297 298 private String dockableName; 299 private StringBuffer code; 300 private boolean actions; 301 302 private Stack stateStack; 303 305 private String pushElement(String name) 307 { 308 name = (name == null) ? null : name.intern(); 309 310 stateStack.push(name); 311 312 return name; 313 } 315 private String peekElement() 317 { 318 return (String ) stateStack.peek(); 319 } 321 private String popElement() 323 { 324 return (String ) stateStack.pop(); 325 } 327 } 330 class Window 332 { 333 PluginJAR plugin; 334 String name; 335 String code; 336 boolean loaded; 337 338 Window(PluginJAR plugin, String name, String code, 340 boolean actions) 341 { 342 this.plugin = plugin; 343 this.name = name; 344 this.code = code; 345 346 if(code != null) 347 loaded = true; 348 349 if(actions) 350 { 351 ActionSet actionSet = (plugin == null 352 ? jEdit.getBuiltInActionSet() 353 : plugin.getActionSet()); 354 actionSet.addAction(new OpenAction(name)); 355 actionSet.addAction(new ToggleAction(name)); 356 actionSet.addAction(new FloatAction(name)); 357 358 String label = jEdit.getProperty(name 359 + ".label"); 360 if(label == null) 361 label = "NO LABEL PROPERTY: " + name; 362 363 String [] args = { label }; 364 jEdit.setTemporaryProperty(name + ".label", 365 label); 366 jEdit.setTemporaryProperty(name 367 + "-toggle.label", 368 jEdit.getProperty( 369 "view.docking.toggle.label",args)); 370 jEdit.setTemporaryProperty(name 371 + "-toggle.toggle","true"); 372 jEdit.setTemporaryProperty(name 373 + "-float.label", 374 jEdit.getProperty( 375 "view.docking.float.label",args)); 376 } 377 } 379 void load() 381 { 382 if(loaded) 383 return; 384 385 loadDockableWindows(plugin,plugin.getDockablesURI(),null); 386 } 388 JComponent createDockableWindow(View view, String position) 390 { 391 load(); 392 393 if(!loaded) 394 { 395 Log.log(Log.WARNING,this,"Outdated cache"); 396 return null; 397 } 398 399 NameSpace nameSpace = new NameSpace( 400 BeanShell.getNameSpace(), 401 "DockableWindowManager.Factory" 402 + ".createDockableWindow()"); 403 try 404 { 405 nameSpace.setVariable( 406 "position",position); 407 } 408 catch(UtilEvalError e) 409 { 410 Log.log(Log.ERROR,this,e); 411 } 412 JComponent win = (JComponent )BeanShell.eval(view, 413 nameSpace,code); 414 return win; 415 } 417 class OpenAction extends EditAction 419 { 420 private String dockable; 421 422 OpenAction(String name) 424 { 425 super(name); 426 this.dockable = name; 427 } 429 public void invoke(View view) 431 { 432 view.getDockableWindowManager() 433 .showDockableWindow(dockable); 434 } 436 public String getCode() 438 { 439 return "view.getDockableWindowManager()" 440 + ".showDockableWindow(\"" + dockable + "\");"; 441 } } 444 class ToggleAction extends EditAction 446 { 447 private String dockable; 448 449 ToggleAction(String name) 451 { 452 super(name + "-toggle"); 453 this.dockable = name; 454 } 456 public void invoke(View view) 458 { 459 view.getDockableWindowManager() 460 .toggleDockableWindow(dockable); 461 } 463 public boolean isSelected(View view) 465 { 466 return view.getDockableWindowManager() 467 .isDockableWindowVisible(dockable); 468 } 470 public String getCode() 472 { 473 return "view.getDockableWindowManager()" 474 + ".toggleDockableWindow(\"" + dockable + "\");"; 475 } } 478 class FloatAction extends EditAction 480 { 481 private String dockable; 482 483 FloatAction(String name) 485 { 486 super(name + "-float"); 487 this.dockable = name; 488 } 490 public void invoke(View view) 492 { 493 view.getDockableWindowManager() 494 .floatDockableWindow(dockable); 495 } 497 public String getCode() 499 { 500 return "view.getDockableWindowManager()" 501 + ".floatDockableWindow(\"" + dockable + "\");"; 502 } } } 506 private static DockableWindowFactory instance; 507 private HashMap <String , Window> dockableWindowFactories; 508 } 509 | Popular Tags |