/jEdit/tags/jedit-4-1-pre3/org/gjt/sp/jedit/gui/DockableWindowManager.java

# · Java · 1209 lines · 817 code · 152 blank · 240 comment · 136 complexity · f32cec698cf08ec0342cdd349309283f MD5 · raw file

  1. /*
  2. * DockableWindowManager.java - manages dockable windows
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 2001 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.EvalError;
  25. import com.microstar.xml.*;
  26. import org.gjt.sp.jedit.browser.VFSBrowser;
  27. import org.gjt.sp.jedit.search.HyperSearchResults;
  28. import org.gjt.sp.jedit.*;
  29. import org.gjt.sp.util.Log;
  30. import javax.swing.*;
  31. import java.awt.event.*;
  32. import java.awt.*;
  33. import java.io.*;
  34. import java.util.*;
  35. //}}}
  36. /**
  37. * Manages dockable windows.
  38. * @author Slava Pestov
  39. * @version $Id: DockableWindowManager.java 4309 2002-08-14 20:11:09Z spestov $
  40. * @since jEdit 2.6pre3
  41. */
  42. public class DockableWindowManager extends JPanel
  43. {
  44. //{{{ Static part of class
  45. //{{{ Constants
  46. /**
  47. * Floating position.
  48. * @since jEdit 2.6pre3
  49. */
  50. public static final String FLOATING = "floating";
  51. /**
  52. * Top position.
  53. * @since jEdit 2.6pre3
  54. */
  55. public static final String TOP = "top";
  56. /**
  57. * Left position.
  58. * @since jEdit 2.6pre3
  59. */
  60. public static final String LEFT = "left";
  61. /**
  62. * Bottom position.
  63. * @since jEdit 2.6pre3
  64. */
  65. public static final String BOTTOM = "bottom";
  66. /**
  67. * Right position.
  68. * @since jEdit 2.6pre3
  69. */
  70. public static final String RIGHT = "right";
  71. //}}}
  72. //{{{ loadDockableWindows() method
  73. /**
  74. * Plugins shouldn't need to call this method.
  75. * @since jEdit 4.0pre1
  76. */
  77. public static boolean loadDockableWindows(String path, Reader in, ActionSet actionSet)
  78. {
  79. try
  80. {
  81. Log.log(Log.DEBUG,jEdit.class,"Loading dockables from " + path);
  82. DockableListHandler dh = new DockableListHandler(path,actionSet);
  83. XmlParser parser = new XmlParser();
  84. parser.setHandler(dh);
  85. parser.parse(null, null, in);
  86. return true;
  87. }
  88. catch(XmlException xe)
  89. {
  90. int line = xe.getLine();
  91. String message = xe.getMessage();
  92. Log.log(Log.ERROR,jEdit.class,path + ":" + line
  93. + ": " + message);
  94. }
  95. catch(Exception e)
  96. {
  97. Log.log(Log.ERROR,jEdit.class,e);
  98. }
  99. return false;
  100. } //}}}
  101. //{{{ registerDockableWindow() method
  102. public static void registerDockableWindow(String name, String code,
  103. boolean actions, ActionSet actionSet)
  104. {
  105. dockableWindowFactories.addElement(new Factory(name,code,
  106. actions,actionSet));
  107. } //}}}
  108. //{{{ getRegisteredDockableWindows() method
  109. public static String[] getRegisteredDockableWindows()
  110. {
  111. String[] retVal = new String[dockableWindowFactories.size()];
  112. for(int i = 0; i < dockableWindowFactories.size(); i++)
  113. {
  114. retVal[i] = ((Factory)dockableWindowFactories.elementAt(i)).name;
  115. }
  116. return retVal;
  117. } //}}}
  118. //{{{ DockableListHandler class
  119. static class DockableListHandler extends HandlerBase
  120. {
  121. //{{{ DockableListHandler constructor
  122. DockableListHandler(String path, ActionSet actionSet)
  123. {
  124. this.path = path;
  125. this.actionSet = actionSet;
  126. stateStack = new Stack();
  127. actions = true;
  128. } //}}}
  129. //{{{ resolveEntity() method
  130. public Object resolveEntity(String publicId, String systemId)
  131. {
  132. if("dockables.dtd".equals(systemId))
  133. {
  134. // this will result in a slight speed up, since we
  135. // don't need to read the DTD anyway, as AElfred is
  136. // non-validating
  137. return new StringReader("<!-- -->");
  138. /* try
  139. {
  140. return new BufferedReader(new InputStreamReader(
  141. getClass().getResourceAsStream
  142. ("/org/gjt/sp/jedit/dockables.dtd")));
  143. }
  144. catch(Exception e)
  145. {
  146. Log.log(Log.ERROR,this,"Error while opening"
  147. + " dockables.dtd:");
  148. Log.log(Log.ERROR,this,e);
  149. } */
  150. }
  151. return null;
  152. } //}}}
  153. //{{{ attribute() method
  154. public void attribute(String aname, String value, boolean isSpecified)
  155. {
  156. aname = (aname == null) ? null : aname.intern();
  157. value = (value == null) ? null : value.intern();
  158. if(aname == "NAME")
  159. dockableName = value;
  160. else if(aname == "NO_ACTIONS")
  161. actions = (value == "FALSE");
  162. } //}}}
  163. //{{{ doctypeDecl() method
  164. public void doctypeDecl(String name, String publicId,
  165. String systemId) throws Exception
  166. {
  167. if("DOCKABLES".equals(name))
  168. return;
  169. Log.log(Log.ERROR,this,path + ": DOCTYPE must be DOCKABLES");
  170. } //}}}
  171. //{{{ charData() method
  172. public void charData(char[] c, int off, int len)
  173. {
  174. String tag = peekElement();
  175. String text = new String(c, off, len);
  176. if (tag == "DOCKABLE")
  177. {
  178. code = text;
  179. }
  180. } //}}}
  181. //{{{ startElement() method
  182. public void startElement(String tag)
  183. {
  184. tag = pushElement(tag);
  185. } //}}}
  186. //{{{ endElement() method
  187. public void endElement(String name)
  188. {
  189. if(name == null)
  190. return;
  191. String tag = peekElement();
  192. if(name.equals(tag))
  193. {
  194. if(tag == "DOCKABLE")
  195. {
  196. registerDockableWindow(dockableName,
  197. code,actions,actionSet);
  198. // make default be true for the next
  199. // action
  200. actions = true;
  201. }
  202. popElement();
  203. }
  204. else
  205. {
  206. // can't happen
  207. throw new InternalError();
  208. }
  209. } //}}}
  210. //{{{ startDocument() method
  211. public void startDocument()
  212. {
  213. try
  214. {
  215. pushElement(null);
  216. }
  217. catch (Exception e)
  218. {
  219. e.printStackTrace();
  220. }
  221. } //}}}
  222. //{{{ Private members
  223. //{{{ Instance variables
  224. private String path;
  225. private ActionSet actionSet;
  226. private String dockableName;
  227. private String code;
  228. private boolean actions;
  229. private Stack stateStack;
  230. //}}}
  231. //{{{ pushElement() method
  232. private String pushElement(String name)
  233. {
  234. name = (name == null) ? null : name.intern();
  235. stateStack.push(name);
  236. return name;
  237. } //}}}
  238. //{{{ peekElement() method
  239. private String peekElement()
  240. {
  241. return (String) stateStack.peek();
  242. } //}}}
  243. //{{{ popElement() method
  244. private String popElement()
  245. {
  246. return (String) stateStack.pop();
  247. } //}}}
  248. //}}}
  249. } //}}}
  250. //{{{ Factory class
  251. static class Factory
  252. {
  253. String name;
  254. String code;
  255. //{{{ Factory constructor
  256. Factory(String name, String code, boolean actions, ActionSet actionSet)
  257. {
  258. this.name = name;
  259. this.code = code;
  260. if(actions)
  261. {
  262. actionSet.addAction(new OpenAction());
  263. actionSet.addAction(new ToggleAction());
  264. actionSet.addAction(new FloatAction());
  265. }
  266. } //}}}
  267. //{{{ createDockableWindow() method
  268. JComponent createDockableWindow(View view, String position)
  269. {
  270. try
  271. {
  272. BeanShell.getNameSpace().setVariable(
  273. "position",position);
  274. }
  275. catch(EvalError e)
  276. {
  277. Log.log(Log.ERROR,this,e);
  278. }
  279. JComponent win = (JComponent)BeanShell.eval(view,
  280. BeanShell.getNameSpace(),code);
  281. return win;
  282. } //}}}
  283. //{{{ OpenAction class
  284. class OpenAction extends EditAction
  285. {
  286. //{{{ OpenAction constructor
  287. OpenAction()
  288. {
  289. super(name);
  290. } //}}}
  291. //{{{ invoke() method
  292. public void invoke(View view)
  293. {
  294. view.getDockableWindowManager()
  295. .showDockableWindow(name);
  296. } //}}}
  297. //{{{ getCode() method
  298. public String getCode()
  299. {
  300. return "view.getDockableWindowManager()"
  301. + ".showDockableWindow(\"" + name + "\");";
  302. } //}}}
  303. } //}}}
  304. //{{{ ToggleAction class
  305. class ToggleAction extends EditAction
  306. {
  307. //{{{ ToggleAction constructor
  308. ToggleAction()
  309. {
  310. super(name + "-toggle");
  311. } //}}}
  312. //{{{ invoke() method
  313. public void invoke(View view)
  314. {
  315. view.getDockableWindowManager()
  316. .toggleDockableWindow(name);
  317. } //}}}
  318. //{{{ isToggle() method
  319. public boolean isToggle()
  320. {
  321. return true;
  322. } //}}}
  323. //{{{ isSelected() method
  324. public boolean isSelected(View view)
  325. {
  326. return view.getDockableWindowManager()
  327. .isDockableWindowVisible(name);
  328. } //}}}
  329. //{{{ getCode() method
  330. public String getCode()
  331. {
  332. return "view.getDockableWindowManager()"
  333. + ".toggleDockableWindow(\"" + name + "\");";
  334. } //}}}
  335. //{{{ getLabel() method
  336. public String getLabel()
  337. {
  338. String[] args = { jEdit.getProperty(name + ".label") };
  339. return jEdit.getProperty("view.docking.toggle.label",args);
  340. } //}}}
  341. } //}}}
  342. //{{{ FloatAction class
  343. class FloatAction extends EditAction
  344. {
  345. //{{{ FloatAction constructor
  346. FloatAction()
  347. {
  348. super(name + "-float");
  349. } //}}}
  350. //{{{ invoke() method
  351. public void invoke(View view)
  352. {
  353. view.getDockableWindowManager()
  354. .floatDockableWindow(name);
  355. } //}}}
  356. //{{{ getCode() method
  357. public String getCode()
  358. {
  359. return "view.getDockableWindowManager()"
  360. + ".floatDockableWindow(\"" + name + "\");";
  361. } //}}}
  362. //{{{ getLabel() method
  363. public String getLabel()
  364. {
  365. String[] args = { jEdit.getProperty(name + ".label") };
  366. return jEdit.getProperty("view.docking.float.label",args);
  367. } //}}}
  368. } //}}}
  369. } //}}}
  370. private static Vector dockableWindowFactories;
  371. //{{{ Static initializer
  372. static
  373. {
  374. dockableWindowFactories = new Vector();
  375. } //}}}
  376. //}}}
  377. //{{{ Instance part of class
  378. //{{{ DockableWindowManager constructor
  379. /**
  380. * Creates a new dockable window manager.
  381. * @param view The view
  382. * @since jEdit 2.6pre3
  383. */
  384. public DockableWindowManager(View view)
  385. {
  386. setLayout(new DockableLayout());
  387. this.view = view;
  388. windows = new Hashtable();
  389. top = new PanelWindowContainer(this,TOP);
  390. left = new PanelWindowContainer(this,LEFT);
  391. bottom = new PanelWindowContainer(this,BOTTOM);
  392. right = new PanelWindowContainer(this,RIGHT);
  393. add(DockableLayout.TOP_BUTTONS,top.getButtonBox());
  394. add(DockableLayout.LEFT_BUTTONS,left.getButtonBox());
  395. add(DockableLayout.BOTTOM_BUTTONS,bottom.getButtonBox());
  396. add(DockableLayout.RIGHT_BUTTONS,right.getButtonBox());
  397. add(TOP,top.getDockablePanel());
  398. add(LEFT,left.getDockablePanel());
  399. add(BOTTOM,bottom.getDockablePanel());
  400. add(RIGHT,right.getDockablePanel());
  401. } //}}}
  402. //{{{ init() method
  403. /**
  404. * Initialises dockable window manager.
  405. * @since jEdit 2.6pre3
  406. */
  407. public void init()
  408. {
  409. for(int i = 0; i < dockableWindowFactories.size(); i++)
  410. {
  411. Factory factory = (Factory)
  412. dockableWindowFactories.elementAt(i);
  413. Entry e;
  414. if(view.isPlainView())
  415. e = new Entry(factory,FLOATING);
  416. else
  417. e = new Entry(factory);
  418. windows.put(factory.name,e);
  419. }
  420. if(!view.isPlainView())
  421. {
  422. String lastTop = jEdit.getProperty("view.dock.top.last");
  423. if(lastTop != null)
  424. showDockableWindow(lastTop);
  425. String lastLeft = jEdit.getProperty("view.dock.left.last");
  426. if(lastLeft != null)
  427. showDockableWindow(lastLeft);
  428. String lastBottom = jEdit.getProperty("view.dock.bottom.last");
  429. if(lastBottom != null)
  430. showDockableWindow(lastBottom);
  431. String lastRight = jEdit.getProperty("view.dock.right.last");
  432. if(lastRight != null)
  433. showDockableWindow(lastRight);
  434. }
  435. } //}}}
  436. //{{{ getView() method
  437. /**
  438. * Returns this dockable window manager's view.
  439. * @since jEdit 4.0pre2
  440. */
  441. public View getView()
  442. {
  443. return view;
  444. } //}}}
  445. //{{{ floatDockableWindow() method
  446. /**
  447. * Opens a new instance of the specified dockable window in a floating
  448. * container.
  449. * @param name The dockable window name
  450. * @return The new dockable window instance
  451. * @since jEdit 4.1pre2
  452. */
  453. public JComponent floatDockableWindow(String name)
  454. {
  455. Entry entry = (Entry)windows.get(name);
  456. if(entry == null)
  457. {
  458. Log.log(Log.ERROR,this,"Unknown dockable window: " + name);
  459. return null;
  460. }
  461. // create a copy of this dockable window and float it
  462. Entry newEntry = new Entry(entry.factory,FLOATING);
  463. newEntry.open();
  464. if(newEntry.win != null)
  465. newEntry.container.show(newEntry);
  466. return newEntry.win;
  467. } //}}}
  468. //{{{ showDockableWindow() method
  469. /**
  470. * Opens the specified dockable window.
  471. * @param name The dockable window name
  472. * @since jEdit 2.6pre3
  473. */
  474. public void showDockableWindow(String name)
  475. {
  476. Entry entry = (Entry)windows.get(name);
  477. if(entry == null)
  478. {
  479. Log.log(Log.ERROR,this,"Unknown dockable window: " + name);
  480. return;
  481. }
  482. if(entry.win == null)
  483. entry.open();
  484. if(entry.win != null)
  485. entry.container.show(entry);
  486. else
  487. /* an error occurred */;
  488. } //}}}
  489. //{{{ addDockableWindow() method
  490. /**
  491. * Opens the specified dockable window. As of version 4.0pre1, has the same
  492. * effect as calling showDockableWindow().
  493. * @param name The dockable window name
  494. * @since jEdit 2.6pre3
  495. */
  496. public void addDockableWindow(String name)
  497. {
  498. showDockableWindow(name);
  499. } //}}}
  500. //{{{ removeDockableWindow() method
  501. /**
  502. * Removes the specified dockable window.
  503. * @param name The dockable window name
  504. * @since jEdit 2.6pre3
  505. */
  506. public void removeDockableWindow(String name)
  507. {
  508. Entry entry = (Entry)windows.get(name);
  509. if(entry == null)
  510. {
  511. Log.log(Log.ERROR,this,"This DockableWindowManager"
  512. + " does not have a window named " + name);
  513. return;
  514. }
  515. if(entry.win == null)
  516. return;
  517. if(entry.container instanceof FloatingWindowContainer)
  518. {
  519. entry.container.save(entry);
  520. entry.container.remove(entry);
  521. entry.container = null;
  522. entry.win = null;
  523. }
  524. else
  525. entry.container.show(null);
  526. } //}}}
  527. //{{{ toggleDockableWindow() method
  528. /**
  529. * Toggles the visibility of the specified dockable window.
  530. * @param name The dockable window name
  531. */
  532. public void toggleDockableWindow(String name)
  533. {
  534. if(isDockableWindowVisible(name))
  535. removeDockableWindow(name);
  536. else
  537. addDockableWindow(name);
  538. } //}}}
  539. //{{{ getDockableWindow() method
  540. /**
  541. * Returns the specified dockable window.
  542. * @param name The name of the dockable window
  543. * @since jEdit 4.1pre2
  544. */
  545. public JComponent getDockableWindow(String name)
  546. {
  547. return getDockable(name);
  548. } //}}}
  549. //{{{ getDockable() method
  550. /**
  551. * Returns the specified dockable window. For historical reasons, this
  552. * does the same thing as <code>getDockableWindow()</code>.
  553. * @param name The name of the dockable window
  554. * @since jEdit 4.0pre1
  555. */
  556. public JComponent getDockable(String name)
  557. {
  558. Entry entry = (Entry)windows.get(name);
  559. if(entry == null || entry.win == null)
  560. return null;
  561. else
  562. return entry.win;
  563. } //}}}
  564. //{{{ isDockableWindowVisible() method
  565. /**
  566. * Returns if the specified dockable window is visible.
  567. * @param name The dockable window name
  568. */
  569. public boolean isDockableWindowVisible(String name)
  570. {
  571. Entry entry = (Entry)windows.get(name);
  572. if(entry == null || entry.win == null)
  573. return false;
  574. else
  575. return entry.container.isVisible(entry);
  576. } //}}}
  577. //{{{ isDockableWindowDocked() method
  578. /**
  579. * Returns if the specified dockable window is docked into the
  580. * view.
  581. * @param name The dockable's name
  582. * @since jEdit 4.0pre2
  583. */
  584. public boolean isDockableWindowDocked(String name)
  585. {
  586. Entry entry = (Entry)windows.get(name);
  587. if(entry == null)
  588. return false;
  589. else
  590. return (entry.position != FLOATING);
  591. } //}}}
  592. //{{{ closeCurrentArea() method
  593. /**
  594. * Closes the currently focused docking area.
  595. * @since jEdit 4.1pre3
  596. */
  597. public void closeCurrentArea()
  598. {
  599. Component comp = view.getFocusOwner();
  600. while(comp != null)
  601. {
  602. System.err.println(comp.getClass());
  603. if(comp instanceof PanelWindowContainer
  604. .DockablePanel)
  605. {
  606. PanelWindowContainer container =
  607. ((PanelWindowContainer.DockablePanel)
  608. comp).getWindowContainer();
  609. container.show(null);
  610. return;
  611. }
  612. comp = comp.getParent();
  613. }
  614. getToolkit().beep();
  615. } //}}}
  616. //{{{ close() method
  617. /**
  618. * Called when the view is being closed.
  619. * @since jEdit 2.6pre3
  620. */
  621. public void close()
  622. {
  623. if(!view.isPlainView())
  624. {
  625. top.save();
  626. left.save();
  627. bottom.save();
  628. right.save();
  629. }
  630. Enumeration enum = windows.elements();
  631. while(enum.hasMoreElements())
  632. {
  633. Entry entry = (Entry)enum.nextElement();
  634. if(entry.win != null)
  635. entry.remove();
  636. }
  637. } //}}}
  638. //{{{ getTopDockingArea() method
  639. public PanelWindowContainer getTopDockingArea()
  640. {
  641. return top;
  642. } //}}}
  643. //{{{ getLeftDockingArea() method
  644. public PanelWindowContainer getLeftDockingArea()
  645. {
  646. return left;
  647. } //}}}
  648. //{{{ getBottomDockingArea() method
  649. public PanelWindowContainer getBottomDockingArea()
  650. {
  651. return bottom;
  652. } //}}}
  653. //{{{ getRightDockingArea() method
  654. public PanelWindowContainer getRightDockingArea()
  655. {
  656. return right;
  657. } //}}}
  658. //{{{ propertiesChanged() method
  659. /**
  660. * Called by the view when properties change.
  661. * @since jEdit 2.6pre3
  662. */
  663. public void propertiesChanged()
  664. {
  665. alternateLayout = jEdit.getBooleanProperty("view.docking.alternateLayout");
  666. Enumeration enum = windows.elements();
  667. while(enum.hasMoreElements())
  668. {
  669. Entry entry = (Entry)enum.nextElement();
  670. String position = entry.position;
  671. String newPosition = jEdit.getProperty(entry.factory.name
  672. + ".dock-position");
  673. if(newPosition != null /* ??? */
  674. && !newPosition.equals(position))
  675. {
  676. entry.position = newPosition;
  677. if(entry.container != null)
  678. {
  679. entry.container.remove(entry);
  680. entry.container = null;
  681. entry.win = null;
  682. }
  683. if(newPosition.equals(FLOATING))
  684. /* do nothing */;
  685. else
  686. {
  687. if(newPosition.equals(TOP))
  688. entry.container = top;
  689. else if(newPosition.equals(LEFT))
  690. entry.container = left;
  691. else if(newPosition.equals(BOTTOM))
  692. entry.container = bottom;
  693. else if(newPosition.equals(RIGHT))
  694. entry.container = right;
  695. else
  696. throw new InternalError("Unknown position: " + newPosition);
  697. entry.container.register(entry);
  698. }
  699. }
  700. if(entry.container instanceof FloatingWindowContainer)
  701. {
  702. SwingUtilities.updateComponentTreeUI(((JFrame)entry.container)
  703. .getRootPane());
  704. }
  705. }
  706. } //}}}
  707. //{{{ Private members
  708. private View view;
  709. private Hashtable windows;
  710. private boolean alternateLayout;
  711. private PanelWindowContainer left;
  712. private PanelWindowContainer right;
  713. private PanelWindowContainer top;
  714. private PanelWindowContainer bottom;
  715. //}}}
  716. //}}}
  717. //{{{ DockableLayout class
  718. public class DockableLayout implements LayoutManager2
  719. {
  720. // for backwards compatibility with plugins that fiddle with
  721. // jEdit's UI layout
  722. static final String CENTER = BorderLayout.CENTER;
  723. public static final String TOP_TOOLBARS = "top-toolbars";
  724. public static final String BOTTOM_TOOLBARS = "bottom-toolbars";
  725. static final String TOP_BUTTONS = "top-buttons";
  726. static final String LEFT_BUTTONS = "left-buttons";
  727. static final String BOTTOM_BUTTONS = "bottom-buttons";
  728. static final String RIGHT_BUTTONS = "right-buttons";
  729. Component topToolbars, bottomToolbars;
  730. Component center;
  731. Component top, left, bottom, right;
  732. Component topButtons, leftButtons, bottomButtons, rightButtons;
  733. //{{{ addLayoutComponent() method
  734. public void addLayoutComponent(String name, Component comp)
  735. {
  736. addLayoutComponent(comp,name);
  737. } //}}}
  738. //{{{ addLayoutComponent() method
  739. public void addLayoutComponent(Component comp, Object cons)
  740. {
  741. if(cons == null || CENTER.equals(cons))
  742. center = comp;
  743. else if(TOP_TOOLBARS.equals(cons))
  744. topToolbars = comp;
  745. else if(BOTTOM_TOOLBARS.equals(cons))
  746. bottomToolbars = comp;
  747. else if(TOP.equals(cons))
  748. top = comp;
  749. else if(LEFT.equals(cons))
  750. left = comp;
  751. else if(BOTTOM.equals(cons))
  752. bottom = comp;
  753. else if(RIGHT.equals(cons))
  754. right = comp;
  755. else if(TOP_BUTTONS.equals(cons))
  756. topButtons = comp;
  757. else if(LEFT_BUTTONS.equals(cons))
  758. leftButtons = comp;
  759. else if(BOTTOM_BUTTONS.equals(cons))
  760. bottomButtons = comp;
  761. else if(RIGHT_BUTTONS.equals(cons))
  762. rightButtons = comp;
  763. } //}}}
  764. //{{{ removeLayoutComponent() method
  765. public void removeLayoutComponent(Component comp)
  766. {
  767. if(center == comp)
  768. center = null;
  769. if(comp == topToolbars)
  770. topToolbars = null;
  771. if(comp == bottomToolbars)
  772. bottomToolbars = null;
  773. {
  774. // none of the others are ever meant to be
  775. // removed. retarded, eh? this needs to be
  776. // fixed eventually, for plugins might
  777. // want to do weird stuff to jEdit's UI
  778. }
  779. } //}}}
  780. //{{{ preferredLayoutSize() method
  781. public Dimension preferredLayoutSize(Container parent)
  782. {
  783. Dimension prefSize = new Dimension(0,0);
  784. Dimension _top = top.getPreferredSize();
  785. Dimension _left = left.getPreferredSize();
  786. Dimension _bottom = bottom.getPreferredSize();
  787. Dimension _right = right.getPreferredSize();
  788. Dimension _topButtons = topButtons.getPreferredSize();
  789. Dimension _leftButtons = leftButtons.getPreferredSize();
  790. Dimension _bottomButtons = bottomButtons.getPreferredSize();
  791. Dimension _rightButtons = rightButtons.getPreferredSize();
  792. Dimension _center = (center == null
  793. ? new Dimension(0,0)
  794. : center.getPreferredSize());
  795. Dimension _topToolbars = (topToolbars == null
  796. ? new Dimension(0,0)
  797. : topToolbars.getPreferredSize());
  798. Dimension _bottomToolbars = (bottomToolbars == null
  799. ? new Dimension(0,0)
  800. : bottomToolbars.getPreferredSize());
  801. prefSize.height = _top.height + _bottom.height + _center.height
  802. + _topButtons.height + _bottomButtons.height
  803. + _topToolbars.height + _bottomToolbars.height;
  804. prefSize.width = _left.width + _right.width
  805. + Math.max(_center.width,
  806. Math.max(_topToolbars.width,_bottomToolbars.width))
  807. + _leftButtons.width + _rightButtons.width;
  808. return prefSize;
  809. } //}}}
  810. //{{{ minimumLayoutSize() method
  811. public Dimension minimumLayoutSize(Container parent)
  812. {
  813. // I'm lazy
  814. return preferredLayoutSize(parent);
  815. } //}}}
  816. //{{{ maximumLayoutSize() method
  817. public Dimension maximumLayoutSize(Container parent)
  818. {
  819. return new Dimension(Integer.MAX_VALUE,Integer.MAX_VALUE);
  820. } //}}}
  821. //{{{ layoutContainer() method
  822. public void layoutContainer(Container parent)
  823. {
  824. Dimension size = parent.getSize();
  825. Dimension _topButtons = topButtons.getPreferredSize();
  826. Dimension _leftButtons = leftButtons.getPreferredSize();
  827. Dimension _bottomButtons = bottomButtons.getPreferredSize();
  828. Dimension _rightButtons = rightButtons.getPreferredSize();
  829. Dimension _center = (center == null
  830. ? new Dimension(0,0)
  831. : center.getPreferredSize());
  832. Dimension _topToolbars = (topToolbars == null
  833. ? new Dimension(0,0)
  834. : topToolbars.getPreferredSize());
  835. Dimension _bottomToolbars = (bottomToolbars == null
  836. ? new Dimension(0,0)
  837. : bottomToolbars.getPreferredSize());
  838. int _width = size.width - _leftButtons.width - _rightButtons.width;
  839. int _height = size.height - _topButtons.height - _bottomButtons.height;
  840. Dimension _top = top.getPreferredSize();
  841. Dimension _left = left.getPreferredSize();
  842. Dimension _bottom = bottom.getPreferredSize();
  843. Dimension _right = right.getPreferredSize();
  844. int topHeight = Math.min(Math.max(0,_height - _bottom.height),_top.height);
  845. int leftWidth = Math.min(Math.max(0,_width - _right.width),_left.width);
  846. int bottomHeight = Math.min(Math.max(0,_height - topHeight),_bottom.height);
  847. int rightWidth = Math.min(Math.max(0,_width - leftWidth),_right.width);
  848. DockableWindowManager.this.top.setDimension(topHeight);
  849. DockableWindowManager.this.left.setDimension(leftWidth);
  850. DockableWindowManager.this.bottom.setDimension(bottomHeight);
  851. DockableWindowManager.this.right.setDimension(rightWidth);
  852. if(alternateLayout)
  853. {
  854. topButtons.setBounds(
  855. _leftButtons.width,
  856. 0,
  857. _width,
  858. _topButtons.height);
  859. leftButtons.setBounds(
  860. 0,
  861. _topButtons.height + _top.height,
  862. _leftButtons.width,
  863. _height - _top.height - _bottom.height);
  864. bottomButtons.setBounds(
  865. _leftButtons.width,
  866. size.height - _bottomButtons.height,
  867. _width,
  868. _bottomButtons.height);
  869. rightButtons.setBounds(
  870. size.width - _rightButtons.width,
  871. _topButtons.height + _top.height,
  872. _rightButtons.width,
  873. _height - _top.height - _bottom.height);
  874. top.setBounds(
  875. _leftButtons.width,
  876. _topButtons.height,
  877. _width,
  878. topHeight);
  879. bottom.setBounds(
  880. _leftButtons.width,
  881. size.height - bottomHeight - _bottomButtons.height,
  882. _width,
  883. bottomHeight);
  884. left.setBounds(
  885. _leftButtons.width,
  886. _topButtons.height + topHeight,
  887. leftWidth,
  888. _height - topHeight - bottomHeight);
  889. right.setBounds(
  890. size.width - rightWidth - _rightButtons.width,
  891. _topButtons.height + topHeight,
  892. rightWidth,
  893. _height - topHeight - bottomHeight);
  894. }
  895. else
  896. {
  897. topButtons.setBounds(
  898. _leftButtons.width + leftWidth,
  899. 0,
  900. _width - leftWidth - rightWidth,
  901. _topButtons.height);
  902. leftButtons.setBounds(
  903. 0,
  904. _topButtons.height,
  905. _leftButtons.width,
  906. _height);
  907. bottomButtons.setBounds(
  908. _leftButtons.width + leftWidth,
  909. size.height - _bottomButtons.height,
  910. _width - leftWidth - rightWidth,
  911. _bottomButtons.height);
  912. rightButtons.setBounds(
  913. size.width - _rightButtons.width,
  914. _topButtons.height,
  915. _rightButtons.width,
  916. _height);
  917. top.setBounds(
  918. _leftButtons.width + leftWidth,
  919. _topButtons.height,
  920. _width - leftWidth - rightWidth,
  921. topHeight);
  922. bottom.setBounds(
  923. _leftButtons.width + leftWidth,
  924. size.height - bottomHeight - _bottomButtons.height,
  925. _width - leftWidth - rightWidth,
  926. bottomHeight);
  927. left.setBounds(
  928. _leftButtons.width,
  929. _topButtons.height,
  930. leftWidth,
  931. _height);
  932. right.setBounds(
  933. size.width - rightWidth - _rightButtons.width,
  934. _topButtons.height,
  935. rightWidth,
  936. _height);
  937. }
  938. if(topToolbars != null)
  939. {
  940. topToolbars.setBounds(
  941. _leftButtons.width + _left.width,
  942. _topButtons.height + _top.height,
  943. _width - _left.width - _right.width,
  944. _topToolbars.height);
  945. }
  946. if(bottomToolbars != null)
  947. {
  948. bottomToolbars.setBounds(
  949. _leftButtons.width + _left.width,
  950. _height - _bottom.height
  951. - _bottomToolbars.height
  952. + _topButtons.height,
  953. _width - _left.width - _right.width,
  954. _bottomToolbars.height);
  955. }
  956. if(center != null)
  957. {
  958. center.setBounds(
  959. _leftButtons.width + _left.width,
  960. _topButtons.height + _top.height
  961. + _topToolbars.height,
  962. _width - _left.width - _right.width,
  963. _height - _top.height - _bottom.height
  964. - _topToolbars.height
  965. - _bottomToolbars.height);
  966. }
  967. } //}}}
  968. //{{{ getLayoutAlignmentX() method
  969. public float getLayoutAlignmentX(Container target)
  970. {
  971. return 0.5f;
  972. } //}}}
  973. //{{{ getLayoutAlignmentY() method
  974. public float getLayoutAlignmentY(Container target)
  975. {
  976. return 0.5f;
  977. } //}}}
  978. //{{{ invalidateLayout() method
  979. public void invalidateLayout(Container target) {}
  980. //}}}
  981. } //}}}
  982. //{{{ Entry class
  983. class Entry
  984. {
  985. Factory factory;
  986. String title;
  987. String position;
  988. DockableWindowContainer container;
  989. // only set if open
  990. JComponent win;
  991. //{{{ Entry constructor
  992. Entry(Factory factory)
  993. {
  994. this(factory,jEdit.getProperty(factory.name
  995. + ".dock-position",FLOATING));
  996. } //}}}
  997. //{{{ Entry constructor
  998. Entry(Factory factory, String position)
  999. {
  1000. this.factory = factory;
  1001. this.position = position;
  1002. // get the title here, not in the factory constructor,
  1003. // since the factory might be created before a plugin's
  1004. // props are loaded
  1005. title = jEdit.getProperty(factory.name + ".title");
  1006. if(title == null)
  1007. title = "NO TITLE PROPERTY: " + factory.name;
  1008. if(position == null)
  1009. position = FLOATING;
  1010. else if(position.equals(FLOATING))
  1011. /* do nothing */;
  1012. else
  1013. {
  1014. if(position.equals(TOP))
  1015. container = top;
  1016. else if(position.equals(LEFT))
  1017. container = left;
  1018. else if(position.equals(BOTTOM))
  1019. container = bottom;
  1020. else if(position.equals(RIGHT))
  1021. container = right;
  1022. else
  1023. throw new InternalError("Unknown position: " + position);
  1024. container.register(this);
  1025. }
  1026. } //}}}
  1027. //{{{ open() method
  1028. void open()
  1029. {
  1030. win = factory.createDockableWindow(view,position);
  1031. if(win == null)
  1032. {
  1033. // error occurred
  1034. return;
  1035. }
  1036. Log.log(Log.DEBUG,this,"Adding " + factory.name + " with position " + position);
  1037. if(position.equals(FLOATING))
  1038. {
  1039. container = new FloatingWindowContainer(
  1040. DockableWindowManager.this);
  1041. container.register(this);
  1042. }
  1043. container.add(this);
  1044. } //}}}
  1045. //{{{ remove() method
  1046. void remove()
  1047. {
  1048. Log.log(Log.DEBUG,this,"Removing " + factory.name + " from "
  1049. + container);
  1050. container.save(this);
  1051. container.remove(this);
  1052. if(container instanceof FloatingWindowContainer)
  1053. container = null;
  1054. win = null;
  1055. } //}}}
  1056. } //}}}
  1057. }