From: <sh...@us...> - 2008-08-10 20:54:58
|
Revision: 13259 http://jedit.svn.sourceforge.net/jedit/?rev=13259&view=rev Author: shlomy Date: 2008-08-10 20:54:46 +0000 (Sun, 10 Aug 2008) Log Message: ----------- Merging my docking_framework branch back into the main trunk. This adds a few new features to the jEdit core: 1. A pluggable docking framework, which can be provided as a service by plugins. To choose the docking framework, use Global Options -> Docking. The original jEdit dockable window manager is named 'Original'. If you get the MyDoggyPlugin plugin, you can select between Original and MyDoggy. 2. Named perspectives - you can now save the docking layout in a file, and load it any time later from a file. Also, once you save the layout in a file, you get an action that loads the layout from this file, and you can bind this action to a keyboard shortcut or toolbar button just like any other action. The actions to load/save the layout are available through the View->Docking menu, and the action set for keyboard shortcuts or toolbar buttons is named "Docking layouts" (in Global Options dialog). 3. Mode-specific perspectives - you can associate the docking layout with an edit mode, each edit mode having its own layout. You can have jEdit automatically save the layout of an edit mode when you switch to another, and automatically load the layout of an edit mode when you enter the mode. The auto load/save of mode-specific layout can be set using Global Options -> Docking. Implementation-wise, several major changes were done to support a pluggable docking framework: 1. Management of toolbars and split configuration (of edit panes) is managed entirely by the core - the docking framework is unaware of it. The framework just gets a panel to be used as the center component, and the core sets its contents with the split configuration and the toolbars when needed. 2. The docking layout has been abstracted out of ViewConfig, and is now delegated to the docking framework for persistence. 3. A new DockingLayoutManager class listens to edit bus messages and responds to edit mode changes by saving/loading the docking layout if the appropriate options are set. Modified Paths: -------------- jEdit/trunk/org/gjt/sp/jedit/GUIUtilities.java jEdit/trunk/org/gjt/sp/jedit/PerspectiveManager.java jEdit/trunk/org/gjt/sp/jedit/SettingsXML.java jEdit/trunk/org/gjt/sp/jedit/View.java jEdit/trunk/org/gjt/sp/jedit/actions.xml jEdit/trunk/org/gjt/sp/jedit/gui/DockableLayout.java jEdit/trunk/org/gjt/sp/jedit/gui/DockablePanel.java jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowContainer.java jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowFactory.java jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowManager.java jEdit/trunk/org/gjt/sp/jedit/gui/FloatingWindowContainer.java jEdit/trunk/org/gjt/sp/jedit/gui/PanelWindowContainer.java jEdit/trunk/org/gjt/sp/jedit/jEdit.java jEdit/trunk/org/gjt/sp/jedit/jedit_gui.props jEdit/trunk/org/gjt/sp/jedit/options/DockingOptionPane.java jEdit/trunk/org/gjt/sp/jedit/services.xml Added Paths: ----------- jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowManagerImpl.java jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowManagerProvider.java jEdit/trunk/org/gjt/sp/jedit/gui/DockingLayoutManager.java jEdit/trunk/org/gjt/sp/jedit/gui/IDockingFrameworkProvider.java Property Changed: ---------------- jEdit/trunk/ jEdit/trunk/org/gjt/sp/util/ReverseCharSequence.java Property changes on: jEdit/trunk ___________________________________________________________________ Added: svn:mergeinfo + /jEdit/branches/docking_framework:13128-13258 Modified: jEdit/trunk/org/gjt/sp/jedit/GUIUtilities.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/GUIUtilities.java 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/GUIUtilities.java 2008-08-10 20:54:46 UTC (rev 13259) @@ -1171,7 +1171,7 @@ } //}}} //{{{ UnixWorkaround class - static class UnixWorkaround + public static class UnixWorkaround { Window win; String name; @@ -1181,7 +1181,7 @@ boolean windowOpened; //{{{ UnixWorkaround constructor - UnixWorkaround(Window win, String name, Rectangle desired, + public UnixWorkaround(Window win, String name, Rectangle desired, int extState) { this.win = win; Modified: jEdit/trunk/org/gjt/sp/jedit/PerspectiveManager.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/PerspectiveManager.java 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/PerspectiveManager.java 2008-08-10 20:54:46 UTC (rev 13259) @@ -22,12 +22,14 @@ package org.gjt.sp.jedit; +import java.io.File; import java.io.IOException; import java.util.LinkedList; import java.util.Collection; import org.xml.sax.Attributes; import org.xml.sax.InputSource; +import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import org.gjt.sp.util.Log; @@ -118,7 +120,8 @@ if(perspectiveXML == null) return; - + File perspectiveFile = new File(perspectiveXML.toString()); + // backgrounded if(jEdit.getBufferCount() == 0) return; @@ -205,25 +208,8 @@ out.write("\" />"); out.write(lineSep); - out.write("<DOCKING LEFT=\""); - out.write(config.left == null ? "" : config.left); - out.write("\" TOP=\""); - out.write(config.top == null ? "" : config.top); - out.write("\" RIGHT=\""); - out.write(config.right == null ? "" : config.right); - out.write("\" BOTTOM=\""); - out.write(config.bottom == null ? "" : config.bottom); - out.write("\" LEFT_POS=\""); - out.write(String.valueOf(config.leftPos)); - out.write("\" TOP_POS=\""); - out.write(String.valueOf(config.topPos)); - out.write("\" RIGHT_POS=\""); - out.write(String.valueOf(config.rightPos)); - out.write("\" BOTTOM_POS=\""); - out.write(String.valueOf(config.bottomPos)); - out.write("\" />"); - out.write(lineSep); - + config.docking.savePerspective(perspectiveFile, out, lineSep); + out.write("</VIEW>"); out.write(lineSep); } @@ -267,12 +253,15 @@ View.ViewConfig config; boolean restoreFiles; String autoReload, autoReloadDialog; - + DefaultHandler dockingLayoutHandler; + PerspectiveHandler(boolean restoreFiles) { this.restoreFiles = restoreFiles; config = new View.ViewConfig(); charData = new StringBuffer(); + config.docking = View.getDockingFrameworkProvider().createDockingLayout(); + dockingLayoutHandler = config.docking.getPerspectiveHandler(); } @Override @@ -292,6 +281,11 @@ String value = attrs.getValue(i); attribute(name, value); } + try { + dockingLayoutHandler.startElement(uri, localName, qName, attrs); + } catch (SAXException e) { + e.printStackTrace(); + } } private void attribute(String aname, String value) @@ -308,22 +302,6 @@ config.extState = Integer.parseInt(value); else if(aname.equals("PLAIN")) config.plainView = ("TRUE".equals(value)); - else if(aname.equals("TOP")) - config.top = value; - else if(aname.equals("LEFT")) - config.left = value; - else if(aname.equals("BOTTOM")) - config.bottom = value; - else if(aname.equals("RIGHT")) - config.right = value; - else if(aname.equals("TOP_POS")) - config.topPos = Integer.parseInt(value); - else if(aname.equals("LEFT_POS")) - config.leftPos = Integer.parseInt(value); - else if(aname.equals("BOTTOM_POS")) - config.bottomPos = Integer.parseInt(value); - else if(aname.equals("RIGHT_POS")) - config.rightPos = Integer.parseInt(value); else if(aname.equals("AUTORELOAD")) autoReload = value; else if(aname.equals("AUTORELOAD_DIALOG")) @@ -371,7 +349,12 @@ { view = jEdit.newView(view,null,config); config = new View.ViewConfig(); - } + } else + try { + dockingLayoutHandler.endElement(uri, localName, name); + } catch (SAXException e) { + e.printStackTrace(); + } } @Override Modified: jEdit/trunk/org/gjt/sp/jedit/SettingsXML.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/SettingsXML.java 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/SettingsXML.java 2008-08-10 20:54:46 UTC (rev 13259) @@ -43,7 +43,7 @@ * - Making backup on each save. * - Detection of change on disk. */ -class SettingsXML +public class SettingsXML { //{{{ Saver class /** @@ -129,6 +129,11 @@ file = new File(MiscUtilities.constructPath( settingsDirectory, filename)); } //}}} + + public SettingsXML(File f) + { + file = f; + } //{{{ fileExits() method /** Modified: jEdit/trunk/org/gjt/sp/jedit/View.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/View.java 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/View.java 2008-08-10 20:54:46 UTC (rev 13259) @@ -23,30 +23,67 @@ package org.gjt.sp.jedit; //{{{ Imports -import org.gjt.sp.jedit.visitors.JEditVisitorAdapter; -import org.gjt.sp.jedit.visitors.JEditVisitor; -import javax.swing.event.*; -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Rectangle; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.io.IOException; import java.io.StreamTokenizer; import java.io.StringReader; import java.net.Socket; -import java.util.*; +import java.util.ArrayList; import java.util.List; +import java.util.Stack; -import org.gjt.sp.jedit.msg.*; -import org.gjt.sp.jedit.gui.*; -import org.gjt.sp.jedit.search.*; -import org.gjt.sp.jedit.textarea.*; -import org.gjt.sp.jedit.textarea.TextArea; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JSplitPane; +import javax.swing.LayoutFocusTraversalPolicy; +import javax.swing.SwingUtilities; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; + +import org.gjt.sp.jedit.bufferset.BufferSet; +import org.gjt.sp.jedit.bufferset.BufferSetManager; +import org.gjt.sp.jedit.gui.ActionBar; +import org.gjt.sp.jedit.gui.DefaultInputHandler; +import org.gjt.sp.jedit.gui.DockableWindowFactory; +import org.gjt.sp.jedit.gui.DockableWindowManager; +import org.gjt.sp.jedit.gui.HistoryModel; +import org.gjt.sp.jedit.gui.IDockingFrameworkProvider; +import org.gjt.sp.jedit.gui.InputHandler; +import org.gjt.sp.jedit.gui.StatusBar; +import org.gjt.sp.jedit.gui.ToolBarManager; +import org.gjt.sp.jedit.gui.VariableGridLayout; +import org.gjt.sp.jedit.gui.DockableWindowManager.DockingLayout; import org.gjt.sp.jedit.input.InputHandlerProvider; +import org.gjt.sp.jedit.msg.BufferUpdate; +import org.gjt.sp.jedit.msg.EditPaneUpdate; +import org.gjt.sp.jedit.msg.PropertiesChanged; +import org.gjt.sp.jedit.msg.SearchSettingsChanged; +import org.gjt.sp.jedit.msg.ViewUpdate; import org.gjt.sp.jedit.options.GeneralOptionPane; -import org.gjt.sp.jedit.bufferset.BufferSet; -import org.gjt.sp.jedit.bufferset.BufferSetManager; +import org.gjt.sp.jedit.search.CurrentBufferSet; +import org.gjt.sp.jedit.search.SearchAndReplace; +import org.gjt.sp.jedit.search.SearchBar; +import org.gjt.sp.jedit.textarea.JEditTextArea; +import org.gjt.sp.jedit.textarea.ScrollListener; +import org.gjt.sp.jedit.textarea.TextArea; +import org.gjt.sp.jedit.visitors.JEditVisitor; +import org.gjt.sp.jedit.visitors.JEditVisitorAdapter; +import org.gjt.sp.util.Log; import org.gjt.sp.util.StandardUtilities; -import org.gjt.sp.util.Log; //}}} /** @@ -96,6 +133,12 @@ //{{{ ToolBar-related constants + public static final String VIEW_DOCKING_FRAMEWORK_PROPERTY = "view.docking.framework"; + private static final String ORIGINAL_DOCKING_FRAMEWORK = "Original"; + public static final String DOCKING_FRAMEWORK_PROVIDER_SERVICE = + "org.gjt.sp.jedit.gui.DockingFrameworkProvider"; + private static IDockingFrameworkProvider dockingFrameworkProvider = null; + //{{{ Groups /** * The group of tool bars above the DockableWindowManager @@ -215,6 +258,21 @@ return dockableWindowManager; } //}}} + static public String getDockingFrameworkName() { + String framework = jEdit.getProperty( + VIEW_DOCKING_FRAMEWORK_PROPERTY, ORIGINAL_DOCKING_FRAMEWORK); + return framework; + } + static public IDockingFrameworkProvider getDockingFrameworkProvider() { + if (dockingFrameworkProvider == null) + { + String framework = getDockingFrameworkName(); + dockingFrameworkProvider = (IDockingFrameworkProvider) + ServiceManager.getService( + DOCKING_FRAMEWORK_PROVIDER_SERVICE, framework); + } + return dockingFrameworkProvider; + } //{{{ getToolBar() method /** * Returns the view's tool bar. @@ -608,6 +666,15 @@ return split(JSplitPane.HORIZONTAL_SPLIT); } //}}} + private Component mainContent = null; + private void setMainContent(Component c) { + if (mainContent != null) + mainPanel.remove(mainContent); + mainContent = c; + mainPanel.add(mainContent, BorderLayout.CENTER); + mainPanel.revalidate(); + mainPanel.repaint(); + } //{{{ split() method /** * Splits the view. @@ -671,8 +738,8 @@ newSplitPane.setLeftComponent(oldEditPane); newSplitPane.setRightComponent(newEditPane); - oldParent.add(newSplitPane,0); - oldParent.revalidate(); + setMainContent(newSplitPane); + } SwingUtilities.invokeLater(new Runnable() @@ -709,12 +776,8 @@ _editPane.close(); } - JComponent parent = (JComponent)splitPane.getParent(); + setMainContent(editPane); - parent.remove(splitPane); - parent.add(editPane,0); - parent.revalidate(); - splitPane = null; updateTitle(); @@ -766,16 +829,14 @@ else parentSplit.setRightComponent(editPane); parentSplit.setDividerLocation(pos); + parent.revalidate(); } else { - parent.remove(comp); - parent.add(editPane,0); + setMainContent(editPane); splitPane = null; } - parent.revalidate(); - updateTitle(); editPane.focusOnTextArea(); @@ -991,6 +1052,7 @@ config.plainView = isPlainView(); config.splitConfig = getSplitConfig(); config.extState = getExtendedState(); + config.docking = dockableWindowManager.getDockingLayout(config); String prefix = config.plainView ? "plain-view" : "view"; switch (config.extState) { @@ -1024,17 +1086,6 @@ config.height = getHeight(); break; } - - config.top = dockableWindowManager.getTopDockingArea().getCurrent(); - config.left = dockableWindowManager.getLeftDockingArea().getCurrent(); - config.bottom = dockableWindowManager.getBottomDockingArea().getCurrent(); - config.right = dockableWindowManager.getRightDockingArea().getCurrent(); - - config.topPos = dockableWindowManager.getTopDockingArea().getDimension(); - config.leftPos = dockableWindowManager.getLeftDockingArea().getDimension(); - config.bottomPos = dockableWindowManager.getBottomDockingArea().getDimension(); - config.rightPos = dockableWindowManager.getRightDockingArea().getDimension(); - return config; } //}}} @@ -1215,9 +1266,12 @@ setIconImage(GUIUtilities.getEditorIcon()); - dockableWindowManager = new DockableWindowManager(this, - DockableWindowFactory.getInstance(),config); - + mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout()); + dockableWindowManager = getDockingFrameworkProvider().create(this, + DockableWindowFactory.getInstance(), config); + dockableWindowManager.setMainPanel(mainPanel); + topToolBars = new JPanel(new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS, 1)); @@ -1305,7 +1359,8 @@ private boolean closed; private DockableWindowManager dockableWindowManager; - + private JPanel mainPanel; + private JPanel topToolBars; private JPanel bottomToolBars; private ToolBarManager toolBarManager; @@ -1458,25 +1513,16 @@ //{{{ setSplitConfig() method private void setSplitConfig(Buffer buffer, String splitConfig) { - if(editPane != null) - dockableWindowManager.remove(editPane); - - if(splitPane != null) - dockableWindowManager.remove(splitPane); - try { Component comp = restoreSplitConfig(buffer,splitConfig); - dockableWindowManager.add(comp,0); + setMainContent(comp); } catch(IOException e) { // this should never throw an exception. throw new InternalError(); } - - dockableWindowManager.revalidate(); - dockableWindowManager.repaint(); } //}}} //{{{ restoreSplitConfig() method @@ -1635,10 +1681,8 @@ } else { - dockableWindowManager.add(topToolBars, - DockableLayout.TOP_TOOLBARS,0); - dockableWindowManager.add(bottomToolBars, - DockableLayout.BOTTOM_TOOLBARS,0); + mainPanel.add(topToolBars, BorderLayout.NORTH); + mainPanel.add(bottomToolBars, BorderLayout.SOUTH); if (showStatus) getContentPane().add(BorderLayout.SOUTH,status); } @@ -1847,14 +1891,11 @@ //{{{ ViewConfig class public static class ViewConfig { + public int x, y, width, height, extState; public boolean plainView; public String splitConfig; - public int x, y, width, height, extState; - - // dockables - public String top, left, bottom, right; - public int topPos, leftPos, bottomPos, rightPos; - + public DockingLayout docking; + public ViewConfig() { } @@ -1867,7 +1908,7 @@ y = jEdit.getIntegerProperty(prefix + ".y",0); width = jEdit.getIntegerProperty(prefix + ".width",0); height = jEdit.getIntegerProperty(prefix + ".height",0); - extState = jEdit.getIntegerProperty(prefix + ".extendedState",NORMAL); + extState = jEdit.getIntegerProperty(prefix + ".extendedState",JFrame.NORMAL); } public ViewConfig(boolean plainView, String splitConfig, @@ -1883,6 +1924,25 @@ } } //}}} + public void adjust(View parent, ViewConfig config) { + if(config.width != 0 && config.height != 0) + { + Rectangle desired = new Rectangle( + config.x, config.y, config.width, config.height); + if(OperatingSystem.isX11() && Debug.GEOMETRY_WORKAROUND) + { + new GUIUtilities.UnixWorkaround(this,"view",desired,config.extState); + } + else + { + setBounds(desired); + setExtendedState(config.extState); + } + } + else + setLocationRelativeTo(parent); + } + //{{{ MyFocusTraversalPolicy class private static class MyFocusTraversalPolicy extends LayoutFocusTraversalPolicy { @@ -1910,4 +1970,5 @@ } }//}}} //}}} + } Modified: jEdit/trunk/org/gjt/sp/jedit/actions.xml =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/actions.xml 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/actions.xml 2008-08-10 20:54:46 UTC (rev 13259) @@ -692,6 +692,30 @@ </CODE> </ACTION> +<ACTION NAME="perspective-save" NO_REPEAT="TRUE"> + <CODE> + DockingLayoutManager.saveAs(view); + </CODE> +</ACTION> + +<ACTION NAME="perspective-load" NO_REPEAT="TRUE"> + <CODE> + DockingLayoutManager.load(view); + </CODE> +</ACTION> + +<ACTION NAME="perspective-save-current-mode" NO_REPEAT="TRUE"> + <CODE> + DockingLayoutManager.saveCurrentModeLayout(view); + </CODE> +</ACTION> + +<ACTION NAME="perspective-load-current-mode" NO_REPEAT="TRUE"> + <CODE> + DockingLayoutManager.loadCurrentModeLayout(view); + </CODE> +</ACTION> + <ACTION NAME="plugin-manager"> <CODE> PluginManager.showPluginManager(view); Modified: jEdit/trunk/org/gjt/sp/jedit/gui/DockableLayout.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/gui/DockableLayout.java 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/gui/DockableLayout.java 2008-08-10 20:54:46 UTC (rev 13259) @@ -32,16 +32,12 @@ // jEdit's UI layout static final String CENTER = BorderLayout.CENTER; - public static final String TOP_TOOLBARS = "top-toolbars"; - public static final String BOTTOM_TOOLBARS = "bottom-toolbars"; - static final String TOP_BUTTONS = "top-buttons"; static final String LEFT_BUTTONS = "left-buttons"; static final String BOTTOM_BUTTONS = "bottom-buttons"; static final String RIGHT_BUTTONS = "right-buttons"; private boolean alternateLayout; - private Component topToolbars, bottomToolbars; private Component center; /* No good */ @@ -85,10 +81,6 @@ { if(cons == null || CENTER.equals(cons)) center = comp; - else if(TOP_TOOLBARS.equals(cons)) - topToolbars = comp; - else if(BOTTOM_TOOLBARS.equals(cons)) - bottomToolbars = comp; else if(DockableWindowManager.TOP.equals(cons)) top = (DockablePanel)comp; else if(DockableWindowManager.LEFT.equals(cons)) @@ -112,10 +104,6 @@ { if(center == comp) center = null; - else if(comp == topToolbars) - topToolbars = null; - else if(comp == bottomToolbars) - bottomToolbars = null; else if(comp == top) top = null; else if(comp == left) @@ -141,12 +129,8 @@ Dimension _center = (center == null ? new Dimension(0,0) : center.getPreferredSize()); - Dimension _topToolbars = (topToolbars == null - ? new Dimension(0,0) - : topToolbars.getPreferredSize()); - Dimension _bottomToolbars = (bottomToolbars == null - ? new Dimension(0,0) - : bottomToolbars.getPreferredSize()); + Dimension _topToolbars = new Dimension(0,0); + Dimension _bottomToolbars = new Dimension(0,0); prefSize.height = _top.height + _bottom.height + _center.height + _topButtons.height + _bottomButtons.height @@ -177,12 +161,8 @@ { Dimension size = parent.getSize(); - Dimension _topToolbars = (topToolbars == null - ? new Dimension(0,0) - : topToolbars.getPreferredSize()); - Dimension _bottomToolbars = (bottomToolbars == null - ? new Dimension(0,0) - : bottomToolbars.getPreferredSize()); + Dimension _topToolbars = new Dimension(0,0); + Dimension _bottomToolbars = new Dimension(0,0); int topButtonHeight = -1; int bottomButtonHeight = -1; @@ -404,29 +384,6 @@ _height); //}}} } - //{{{ Position tool bars if they are managed by us - if(topToolbars != null) - { - topToolbars.setBounds( - leftButtonWidth + leftWidth, - topButtonHeight + topHeight, - size.width - leftWidth - rightWidth - - leftButtonWidth - rightButtonWidth, - _topToolbars.height); - } - - if(bottomToolbars != null) - { - bottomToolbars.setBounds( - leftButtonWidth + leftWidth, - size.height - bottomHeight - - bottomButtonHeight - - _bottomToolbars.height, - size.width - leftWidth - rightWidth - - leftButtonWidth - rightButtonWidth, - _bottomToolbars.height); - } //}}} - //{{{ Position center (edit pane, or split pane) if(center != null) { Modified: jEdit/trunk/org/gjt/sp/jedit/gui/DockablePanel.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/gui/DockablePanel.java 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/gui/DockablePanel.java 2008-08-10 20:54:46 UTC (rev 13259) @@ -44,7 +44,7 @@ class DockablePanel extends JPanel { private PanelWindowContainer panel; - private DockableWindowManager wm; + private DockableWindowManagerImpl wm; //{{{ DockablePanel constructor DockablePanel(PanelWindowContainer panel) @@ -123,14 +123,14 @@ position.equals(DockableWindowManager.BOTTOM)) { if(dimension != 0 && height <= PanelWindowContainer.SPLITTER_WIDTH) - panel.show(null); + panel.show((DockableWindowManagerImpl.Entry) null); else panel.setDimension(height); } else { if(dimension != 0 && width <= PanelWindowContainer.SPLITTER_WIDTH) - panel.show(null); + panel.show((DockableWindowManagerImpl.Entry) null); else panel.setDimension(width); } Modified: jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowContainer.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowContainer.java 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowContainer.java 2008-08-10 20:54:46 UTC (rev 13259) @@ -28,9 +28,9 @@ */ interface DockableWindowContainer { - void register(DockableWindowManager.Entry entry); - void remove(DockableWindowManager.Entry entry); - void unregister(DockableWindowManager.Entry entry); - void show(DockableWindowManager.Entry entry); - boolean isVisible(DockableWindowManager.Entry entry); + void register(DockableWindowManagerImpl.Entry entry); + void remove(DockableWindowManagerImpl.Entry entry); + void unregister(DockableWindowManagerImpl.Entry entry); + void show(DockableWindowManagerImpl.Entry entry); + boolean isVisible(DockableWindowManagerImpl.Entry entry); } Modified: jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowFactory.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowFactory.java 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowFactory.java 2008-08-10 20:54:46 UTC (rev 13259) @@ -166,6 +166,11 @@ return retVal; } //}}} + public Window getDockableWindowFactory(String name) + { + return dockableWindowFactories.get(name); + } + //{{{ getDockableWindowIterator() method Iterator<Window> getDockableWindowIterator() { Modified: jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowManager.java =================================================================== --- jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowManager.java 2008-08-10 19:30:39 UTC (rev 13258) +++ jEdit/trunk/org/gjt/sp/jedit/gui/DockableWindowManager.java 2008-08-10 20:54:46 UTC (rev 13259) @@ -1,148 +1,35 @@ -/* - * DockableWindowManager.java - manages dockable windows - * :tabSize=8:indentSize=8:noTabs=false: - * :folding=explicit:collapseFolds=1: - * - * Copyright (C) 2000, 2005 Slava Pestov - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - package org.gjt.sp.jedit.gui; -//{{{ Imports -import java.awt.Color; -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; -import java.util.*; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; -import javax.swing.AbstractButton; import javax.swing.JComponent; -import javax.swing.JMenuItem; import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.SwingUtilities; import org.gjt.sp.jedit.EBComponent; import org.gjt.sp.jedit.EBMessage; import org.gjt.sp.jedit.EditBus; -import org.gjt.sp.jedit.PluginJAR; +import org.gjt.sp.jedit.SettingsXML; import org.gjt.sp.jedit.View; import org.gjt.sp.jedit.jEdit; +import org.gjt.sp.jedit.View.ViewConfig; import org.gjt.sp.jedit.gui.KeyEventTranslator.Key; import org.gjt.sp.jedit.msg.DockableWindowUpdate; -import org.gjt.sp.jedit.msg.PluginUpdate; import org.gjt.sp.jedit.msg.PropertiesChanged; import org.gjt.sp.util.Log; -//}}} +import org.xml.sax.helpers.DefaultHandler; -/** - * <p>Keeps track of all dockable windows for a single View, and provides - * an API for getting/showing/hiding them. </p> - * - * <p>Each {@link org.gjt.sp.jedit.View} has an instance of this class.</p> - * - * <p><b>dockables.xml:</b></p> - * - * <p>Dockable window definitions are read from <code>dockables.xml</code> files - * contained inside plugin JARs. A dockable definition file has the following - * form: </p> - * - * <pre><?xml version="1.0"?> - *<!DOCTYPE DOCKABLES SYSTEM "dockables.dtd"> - *<DOCKABLES> - * <DOCKABLE NAME="<i>dockableName</i>" MOVABLE="TRUE|FALSE"> - * // Code to create the dockable - * </DOCKABLE> - *</DOCKABLES></pre> - * - * <p>The MOVABLE attribute specifies the behavior when the docking position of - * the dockable window is changed. If MOVABLE is TRUE, the existing instance of - * the dockable window is moved to the new docking position, and if the dockable - * window implements the DockableWindow interface (see {@link DockableWindow}), - * it is also notified about the change in docking position before it is moved. - * If MOVABLE is FALSE, the BeanShell code is invoked to get the instance of - * the dockable window to put in the new docking position. Typically, the - * BeanShell code returns a new instance of the dockable window, and the state - * of the existing instance is not preserved after the change. It is therefore - * recommended to set MOVABLE to TRUE for all dockables in order to make them - * preserve their state when they are moved. For backward compatibility reasons, - * this attribute is set to FALSE by default.</p> - * <p>More than one <code><DOCKABLE></code> tag may be present. The code that - * creates the dockable can reference any BeanShell built-in variable - * (see {@link org.gjt.sp.jedit.BeanShell}), along with a variable - * <code>position</code> whose value is one of - * {@link #FLOATING}, {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, - * and {@link #RIGHT}. </p> - * - * <p>The following properties must be defined for each dockable window: </p> - * - * <ul> - * <li><code><i>dockableName</i>.title</code> - the string to show on the dockable - * button. </li> - * <li><code><i>dockableName</i>.label</code> - The string to use for generating - * menu items and action names. </li> - * <li><code><i>dockableName</i>.longtitle</code> - (optional) the string to use - * in the dockable's floating window title (when it is floating). - * If not specified, the <code><i>dockableName</i>.title</code> property is used. </li> - * </ul> - * - * A number of actions are automatically created for each dockable window: - * - * <ul> - * <li><code><i>dockableName</i></code> - opens the dockable window.</li> - * <li><code><i>dockableName</i>-toggle</code> - toggles the dockable window's visibility.</li> - * <li><code><i>dockableName</i>-float</code> - opens the dockable window in a new - * floating window.</li> - * </ul> - * - * Note that only the first action needs a <code>label</code> property, the - * rest have automatically-generated labels. - * - * <p> <b>Implementation details:</b></p> - * - * <p> When an instance of this class is initialized by the {@link org.gjt.sp.jedit.View} - * class, it - * iterates through the list of registered dockable windows (from jEdit itself, - * and any loaded plugins) and - * examines options supplied by the user in the <b>Global - * Options</b> dialog box. Any plugins designated for one of the - * four docking positions are displayed.</p> - * - * <p> To create an instance of a dockable window, the <code>DockableWindowManager</code> - * finds and executes the BeanShell code extracted from the appropriate - * <code>dockables.xml</code> file. This code will typically consist of a call - * to the constructor of the dockable window component. The result of the - * BeanShell expression, typically a newly constructed component, is placed - * in a window managed by this class. </p> - * - * @see org.gjt.sp.jedit.View#getDockableWindowManager() - * - * @author Slava Pestov - * @author John Gellene (API documentation) - * @version $Id$ - * @since jEdit 2.6pre3 - */ -public class DockableWindowManager extends JPanel implements EBComponent +@SuppressWarnings("serial") +public abstract class DockableWindowManager extends JPanel implements EBComponent { + //{{{ Constants /** * Floating position. @@ -174,84 +61,69 @@ */ public static final String RIGHT = "right"; //}}} - - //{{{ Data members - private final View view; - private final DockableWindowFactory factory; - /** A mapping from Strings to Entry objects. */ - private final Map<String, Entry> windows; - private final PanelWindowContainer left; - private final PanelWindowContainer right; - private final PanelWindowContainer top; - private final PanelWindowContainer bottom; - private final List<Entry> clones; - - private Entry lastEntry; - public Stack showStack = new Stack(); - // }}} - - //{{{ getRegisteredDockableWindows() method - /** - * @since jEdit 4.3pre2 + public static abstract class DockingLayout { + public DockingLayout() { + } + public void setPlainView(boolean plain) { + } + abstract public DefaultHandler getPerspectiveHandler(); + abstract public void savePerspective(File file, SettingsXML.Saver out, String lineSep) throws IOException; + } + + /* + * Docking framework interface methods */ - public static String[] getRegisteredDockableWindows() + abstract public void setMainPanel(JPanel panel); + public void setDockingLayout(DockingLayout docking) { - return DockableWindowFactory.getInstance() - .getRegisteredDockableWindows(); - } //}}} + // By default, use the docking positions specified by the jEdit properties + Iterator<Entry<String, String>> iterator = positions.entrySet().iterator(); + while (iterator.hasNext()) + { + Entry<String, String> entry = iterator.next(); + String dockable = entry.getKey(); + String position = entry.getValue(); + if (! position.equals(FLOATING)) + showDockableWindow(dockable); + } + } + abstract public void showDockableWindow(String name); + abstract public void hideDockableWindow(String name); + abstract public JComponent floatDockableWindow(String name); + abstract public boolean isDockableWindowDocked(String name); + abstract public boolean isDockableWindowVisible(String name); + abstract public void closeCurrentArea(); + abstract public DockingLayout getDockingLayout(ViewConfig config); + protected void dockingPositionChanged(String dockableName, + String oldPosition, String newPosition) + { + } + public void dockableTitleChanged(String dockable, String newTitle) + { + } + protected interface DockingArea { + void showMostRecent(); + String getCurrent(); + void show(String name); + } + abstract public DockingArea getLeftDockingArea(); + abstract public DockingArea getRightDockingArea(); + abstract public DockingArea getTopDockingArea(); + abstract public DockingArea getBottomDockingArea(); - //{{{ DockableWindowManager constructor - /** - * Creates a new dockable window manager. - * @param view The view - * @param factory A {@link DockableWindowFactory}, usually - * <code>DockableWindowFactory.getInstance()</code>. - * @param config A docking configuration - * @since jEdit 2.6pre3 + /* + * Data members */ - public DockableWindowManager(View view, DockableWindowFactory factory, - View.ViewConfig config) - { - setLayout(new DockableLayout()); - this.view = view; - this.factory = factory; - windows = new HashMap<String, Entry>(); - clones = new ArrayList<Entry>(); - - top = new PanelWindowContainer(this,TOP,config.topPos); - left = new PanelWindowContainer(this,LEFT,config.leftPos); - bottom = new PanelWindowContainer(this,BOTTOM,config.bottomPos); - right = new PanelWindowContainer(this,RIGHT,config.rightPos); - - add(DockableLayout.TOP_BUTTONS,top.buttonPanel); - add(DockableLayout.LEFT_BUTTONS,left.buttonPanel); - add(DockableLayout.BOTTOM_BUTTONS,bottom.buttonPanel); - add(DockableLayout.RIGHT_BUTTONS,right.buttonPanel); - - add(TOP,top.dockablePanel); - add(LEFT,left.dockablePanel); - add(BOTTOM,bottom.dockablePanel); - add(RIGHT,right.dockablePanel); - } //}}} - - //{{{ init() method - /** - * Initialises dockable window manager. Do not call this method directly. + protected View view; + protected DockableWindowFactory factory; + protected Map<String, JComponent> windows = new HashMap<String, JComponent>(); + + /* + * Base class methods */ - public void init() - { - EditBus.addToBus(this); - Iterator<DockableWindowFactory.Window> entries = factory.getDockableWindowIterator(); - - while(entries.hasNext()) - addEntry(entries.next()); - - propertiesChanged(); - } //}}} - // {{{ closeListener() method /** * @@ -282,80 +154,149 @@ return view; } //}}} - //{{{ floatDockableWindow() method + //{{{ getRegisteredDockableWindows() method /** - * Opens a new instance of the specified dockable window in a floating - * container. - * @param name The dockable window name - * @return The new dockable window instance - * @since jEdit 4.1pre2 + * @since jEdit 4.3pre2 */ - public JComponent floatDockableWindow(String name) + public JComponent getDockable(String name) { - Entry entry = windows.get(name); - if(entry == null) - { - Log.log(Log.ERROR,this,"Unknown dockable window: " + name); - return null; - } - - // create a copy of this dockable window and float it - Entry newEntry = new Entry(entry.factory,FLOATING); - newEntry.win = newEntry.factory.createDockableWindow(view,FLOATING); - - if(newEntry.win != null) - { - FloatingWindowContainer fwc = new FloatingWindowContainer(this,true); - newEntry.container = fwc; - newEntry.container.register(newEntry); - newEntry.container.show(newEntry); - - - } - clones.add(newEntry); - return newEntry.win; - } //}}} - - //{{{ showDockableWindow() method + return windows.get(name); + } + + //{{{ getDockableTitle() method /** - * Opens the specified dockable window. - * @param name The dockable window name - * @since jEdit 2.6pre3 + * Returns the title of the specified dockable window. + * @param name The name of the dockable window. + * @since jEdit 4.1pre5 */ - public void showDockableWindow(String name) + public String getDockableTitle(String name) { - lastEntry = windows.get(name); - if(lastEntry == null) + return longTitle(name); + }//}}} + + //{{{ setDockableTitle() method + /** + * Changes the .longtitle property of a dockable window, which corresponds to the + * title shown when it is floating (not docked). Fires a change event that makes sure + * all floating dockables change their title. + * + * @param dockableName the name of the dockable, as specified in the dockables.xml + * @param newTitle the new .longtitle you want to see above it. + * @since 4.3pre5 + * + */ + public void setDockableTitle(String dockable, String title) + { + String propName = getLongTitlePropertyName(dockable); + String oldTitle = jEdit.getProperty(propName); + jEdit.setProperty(propName, title); + firePropertyChange(propName, oldTitle, title); + dockableTitleChanged(dockable, title); + } + // }}} + + //{{{ getDockableTitle() method + public static String[] getRegisteredDockableWindows() + { + return DockableWindowFactory.getInstance() + .getRegisteredDockableWindows(); + } //}}} + + public void handleMessage(EBMessage msg) { + if (msg instanceof DockableWindowUpdate) { - Log.log(Log.ERROR,this,"Unknown dockable window: " + name); + if(((DockableWindowUpdate)msg).getWhat() == DockableWindowUpdate.PROPERTIES_CHANGED) + propertiesChanged(); + } + else if (msg instanceof PropertiesChanged) + propertiesChanged(); + } + + private Map<String, String> positions = new HashMap<String, String>(); + + protected void propertiesChanged() + { + if(view.isPlainView()) return; + + String[] dockables = factory.getRegisteredDockableWindows(); + for(int i = 0; i < dockables.length; i++) + { + String dockable = dockables[i]; + String oldPosition = positions.get(dockable); + String newPosition = getDockablePosition(dockable); + if ((oldPosition == null) || (! newPosition.equals(oldPosition))) + { + positions.put(dockable, newPosition); + dockingPositionChanged(dockable, oldPosition, newPosition); + } } + + } + public DockableWindowManager(View view, DockableWindowFactory instance, + ViewConfig config) + { + this.view = view; + this.factory = instance; + } + public void init() + { + EditBus.addToBus(this); - if(lastEntry.win == null) + Iterator<DockableWindowFactory.Window> entries = factory.getDockableWindowIterator(); + while(entries.hasNext()) { - lastEntry.win = lastEntry.factory.createDockableWindow( - view,lastEntry.position); + DockableWindowFactory.Window window = entries.next(); + String dockable = window.name; + positions.put(dockable, getDockablePosition(dockable)); } + } + public void close() + { + EditBus.removeFromBus(this); + } - if(lastEntry.win != null) + protected JComponent createDockable(String name) + { + DockableWindowFactory.Window wf = factory.getDockableWindowFactory(name); + if (wf == null) { - if(lastEntry.position.equals(FLOATING) - && lastEntry.container == null) - { - FloatingWindowContainer fwc = new FloatingWindowContainer( - this,view.isPlainView()); - lastEntry.container = fwc; - lastEntry.container.register(lastEntry); - } - showStack.push(name); - lastEntry.container.show(lastEntry); - Object reason = DockableWindowUpdate.ACTIVATED; - EditBus.send(new DockableWindowUpdate(this, reason, name)); + Log.log(Log.ERROR,this,"Unknown dockable window: " + name); + return null; } - else - /* an error occurred */; - } //}}} + String position = getDockablePosition(name); + JComponent window = wf.createDockableWindow(view, position); + if (window != null) + windows.put(name, window); + return window; + } + protected String getDockablePosition(String name) + { + return jEdit.getProperty(name + ".dock-position", FLOATING); + } + private String getLongTitlePropertyName(String dockableName) + { + return dockableName + ".longtitle"; + } + public String longTitle(String name) + { + String title = jEdit.getProperty(getLongTitlePropertyName(name)); + if (title == null) + return shortTitle(name); + return title; + } + public String shortTitle(String name) + { + String title = jEdit.getProperty(name + ".title"); + if(title == null) + return "NO TITLE PROPERTY: " + name; + return title; + } + /* + * Derived methods + */ + //{{{ addDockableWindow() method /** * Opens the specified dockable window. As of jEdit 4.0pre1, has the @@ -368,30 +309,7 @@ showDockableWindow(name); } //}}} - //{{{ hideDockableWindow() method - /** - * Hides the specified dockable window. - * @param name The dockable window name - * @since jEdit 2.6pre3 - */ - public void hideDockableWindow(String name) - { - - Entry entry = windows.get(name); - if(entry == null) - { - Log.log(Log.ERROR,this,"Unknown dockable window: " + name); - return; - } - - - - if(entry.win == null) - return; - - entry.container.show(null); - } //}}} - + //{{{ removeDockableWindow() method /** * Hides the specified dockable window. As of jEdit 4.2pre1, has the @@ -404,6 +322,7 @@ hideDockableWindow(name); } //}}} + //{{{ toggleDockableWindow() method /** * Toggles the visibility of the specified dockable window. @@ -433,695 +352,54 @@ return getDockable(name); } //}}} - //{{{ getDockable() method + //{{{ KeyHandler class /** - * Returns the specified dockable window. - * - * Note that this method - * will return null if the dockable has not been added yet. - * Make sure you call {@link #addDockableWindow(String)} first. - * - * For historical reasons, this - * does the same thing as {@link #getDockableWindow(String)}. - * - * @param name The name of the dockable window - * @since jEdit 4.0pre1 - */ - public JComponent getDockable(String name) - { - - Entry entry = windows.get(name); - if(entry == null || entry.win == null) - return null; - else - return entry.win; - } //}}} - - //{{{ getDockableTitle() method - /** - * Returns the title of the specified dockable window. - * @param name The name of the dockable window. - * @since jEdit 4.1pre5 - */ - public String getDockableTitle(String name) - { - Entry e = windows.get(name); - return e.longTitle(); - } //}}} - - //{{{ setDockableTitle() method - /** - * Changes the .longtitle property of a dockable window, which corresponds to the - * title shown when it is floating (not docked). Fires a change event that makes sure - * all floating dockables change their title. + * This keyhandler responds to only two key events - those corresponding to + * the close-docking-area action event. * - * @param dockableName the name of the dockable, as specified in the dockables.xml - * @param newTitle the new .longtitle you want to see above it. - * @since 4.3pre5 - * + * @author ezust */ - public void setDockableTitle(String dockableName, String newTitle) { - Entry entry = windows.get(dockableName); - String propName = entry.factory.name + ".longtitle"; - String oldTitle = jEdit.getProperty(propName); - jEdit.setProperty(propName, newTitle); - firePropertyChange(propName, oldTitle, newTitle); - } - // }}} - - //{{{ isDockableWindowVisible() method - /** - * Returns if the specified dockable window is visible. - * @param name The dockable window name - */ - public boolean isDockableWindowVisible(String name) - { - Entry entry = windows.get(name); - if(entry == null || entry.win == null) - return false; - else - return entry.container.isVisible(entry); - } //}}} - - //{{{ isDockableWindowDocked() method - /** - * Returns if the specified dockable window is docked into the - * view. - * @param name The dockable's name - * @since jEdit 4.0pre2 - */ - public boolean isDockableWindowDocked(String name) - { - Entry entry = windows.get(name); - if(entry == null) - return false; - else - return !entry.position.equals(FLOATING); - } //}}} - - //{{{ closeCurrentArea() method - /** - * Closes the most recently focused dockable. - * @since jEdit 4.1pre3 - */ - public void closeCurrentArea() - { - // I don't know of any other way to fix this, since invoking this - // command from a menu results in the focus owner being the menu - // until the menu goes away. - SwingUtilities.invokeLater(new Runnable() + class KeyHandler extends KeyAdapter { + static final String action = "close-docking-area"; + Key b1, b2; + String name; + + public KeyHandler(String dockableName) { - public void run() - { - /* Try to hide the last entry that was shown */ - try { - String dockableName = showStack.pop().toString(); - hideDockableWindow(dockableName); - return; - } - catch (Exception e) {} - - Component comp = view.getFocusOwner(); - while(comp != null) - { - //System.err.println(comp.getClass()); - if(comp instanceof DockablePanel) - { - DockablePanel panel = (DockablePanel) comp; - - PanelWindowContainer container = panel.getWindowContainer(); - - container.show(null); - return; - } +/* + String prefixStr = null; - comp = comp.getParent(); - } - - getToolkit().beep(); - } - }); - } //}}} - - //{{{ close() method - /** - * Called when the view is being closed. - * @since jEdit 2.6pre3 - */ - public void close() - { - EditBus.removeFromBus(this); - - for (Entry entry : windows.values()) - { - if (entry.win != null) - entry.container.unregister(entry); - } - - for (Entry clone : clones) - { - if (clone.win != null) - clone.container.unregister(clone); - } - } //}}} - - //{{{ getTopDockingArea() method - public PanelWindowContainer getTopDockingArea() - { - return top; - } //}}} - - //{{{ getLeftDockingArea() method - public PanelWindowContainer getLeftDockingArea() - { - return left; - } //}}} - - //{{{ getBottomDockingArea() method - public PanelWindowContainer getBottomDockingArea() - { - return bottom; - } //}}} - - //{{{ getRightDockingArea() method - public PanelWindowContainer getRightDockingArea() - { - return right; - } //}}} - - //{{{ createPopupMenu() method - public JPopupMenu createPopupMenu( - final DockableWindowContainer container, - final String dockable, - final boolean clone) - { - JPopupMenu popup = new JPopupMenu(); - if(dockable == null && container instanceof PanelWindowContainer) - { - ActionListener listener = new ActionListener() + StringTokenizer st = new StringTokenizer(keyBinding); + while(st.hasMoreTokens()) { - public void actionPerformed(ActionEvent evt) - { - showDockableWindow(evt.getActionCommand()); - } - }; + String keyCodeStr = st.nextToken(); + if(prefixStr == null) + prefixStr = keyCodeStr; + else + prefixStr = prefixStr + " " + keyCodeStr; - String[] dockables = ((PanelWindowContainer) - container).getDockables(); - Map<String,String> dockableMap = new TreeMap<String, String>(); - for (int i = 0; i < dockables.length; i++) - { - String action = dockables[i]; - dockableMap.put(getDockableTitle(action), action); - } - for (Map.Entry<String, String> entry : dockableMap.entrySet()) - { - JMenuItem item = new JMenuItem(entry.getKey()); - item.setActionCommand(entry.getValue()); - item.addActionListener(listener); - popup.add(item); - } - } - else - { - JMenuItem caption = new JMenuItem(getDockableTitle(dockable)); - caption.setEnabled(false); - popup.add(caption); - popup.addSeparator(); - String currentPos = jEdit.getProperty(dockable + ".dock-position",FLOATING); - if(!clone) - { - String[] positions = { FLOATING, TOP, LEFT, BOTTOM, RIGHT }; - for(int i = 0; i < positions.length; i++) - { - final String pos = positions[i]; - if(pos.equals(currentPos)) - continue; + KeyEventTranslator.Key keyStroke = KeyEventTranslator.parseKey(keyCodeStr); + if(keyStroke == null) + return; - JMenuItem moveMenuItem = new JMenuItem(jEdit.getProperty("view.docking.menu-" - + pos)); - - moveMenuItem.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent evt) - { - jEdit.setProperty(dockable + ".dock-position",pos); - EditBus.send(new DockableWindowUpdate( - DockableWindowManager.this, - DockableWindowUpdate.PROPERTIES_CHANGED, - null - )); - showDockableWindow(dockable); - } - }); - popup.add(moveMenuItem); - } - - popup.addSeparator(); - } - - JMenuItem cloneMenuItem = new JMenuItem(jEdit.getProperty("view.docking.menu-clone")); - - cloneMenuItem.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent evt) + if(st.hasMoreTokens()) { - floatDockableWindow(dockable); - } - }); - popup.add(cloneMenuItem); - - popup.addSeparator(); - - JMenuItem closeMenuItem = new JMenuItem(jEdit.getProperty("view.docking.menu-close")); - - closeMenuItem.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent evt) - { - if(clone) - ((FloatingWindowContainer)container).dispose(); + Object o = current.get(keyStroke); + if(o instanceof Hashtable) + current = (Hashtable)o; else - removeDockableWindow(dockable); - } - }); - popup.add(closeMenuItem); - - if(!(clone || currentPos.equals(FLOATING))) - { - JMenuItem undockMenuItem = new JMenuItem(jEdit.getProperty("view.docking.menu-undock")); - - undockMenuItem.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent evt) { - jEdit.setProperty(dockable + ".dock-position",FLOATING); - EditBus.send(new DockableWindowUpdate( - DockableWindowManager.this, - DockableWindowUpdate.PROPERTIES_CHANGED, - null - )); - // Reset the window, propertiesChanged() doesn't - // reset it for MOVABLE windows. - Entry entry = windows.get(dockable); - if (entry == null) - Log.log(Log.ERROR,this,"Unknown dockable window: " + dockable); - else - entry.win = null; + Hashtable hash = new Hashtable(); + hash.put(PREFIX_STR,prefixStr); + o = hash; + current.put(keyStroke,o); + current = (Hashtable)o; } - }); - popup.add(undockMenuItem); - } - } - - return popup; - } //}}} - - //{{{ paintChildren() method - public void paintChildren(Graphics g) - { - super.paintChildren(g); - - if(resizeRect != null) - { - g.setColor(Color.darkGray); - g.fillRect(resizeRect.x,resizeRect.y, - resizeRect.width,resizeRect.height); - } - } //}}} - - //{{{ handleMessage() method - public void handleMessage(EBMessage msg) - { - if(msg instanceof DockableWindowUpdate) - { - if(((DockableWindowUpdate)msg).getWhat() - == DockableWindowUpdate.PROPERTIES_CHANGED) - propertiesChanged(); - } - else if(msg instanceof PropertiesChanged) - propertiesChanged(); - else if(msg instanceof PluginUpdate) - { - PluginUpdate pmsg = (PluginUpdate)msg; - if(pmsg.getWhat() == PluginUpdate.LOADED) - { - Iterator<DockableWindowFactory.Window> iter = factory.getDockableWindowIterator(); - - while(iter.hasNext()) - { - DockableWindowFactory.Window w = iter.next(); - if(w.plugin == pmsg.getPluginJAR()) - addEntry(w); } - - propertiesChanged(); - } - else if(pmsg.isExiting()) - { - // we don't care - } - else if(pmsg.getWhat() == PluginUpdate.DEACTIVATED) - { - Iterator<Entry> iter = getAllPluginEntries( - pmsg.getPluginJAR(),false); - while(iter.hasNext()) - { - Entry entry = iter.next(); - if(entry.container != null) - entry.container.remove(entry); - } - } - else if(pmsg.getWhat() == PluginUpdate.UNLOADED) - { - Iterator<Entry> iter = getAllPluginEntries( - pmsg.getPluginJAR(),true); - while(iter.hasNext()) - { - Entry entry = iter.next(); - if(entry.container != null) - { - entry.container.unregister(entry); - entry.win = null; - entry.container = null; - } - } - } - } - } //}}} - - //{{{ Package-private members - int resizePos; - /** - * This is the rectangle you drag to resize the split. - * It is used with non continuous layout. - */ - Rectangle resizeRect; - - //{{{ setResizePos() method - void setResizePos(int resizePos, PanelWindowContainer resizing) - { - this.resizePos = resizePos; - - if(resizePos < 0) - resizePos = 0; - - if (continuousLayout) - return; - - Rectangle newResizeRect = new Rectangle(0,0, - PanelWindowContainer.SPLITTER_WIDTH - 2, - PanelWindowContainer.SPLITTER_WIDTH - 2); - if(resizing == top) - { - resizePos = Math.min(resizePos,getHeight() - - top.buttonPanel.getHeight() - - bottom.dockablePanel.getHeight() - - bottom.buttonPanel.getHeight() - - PanelWindowContainer.SPLITTER_WIDTH); - newResizeRect.x = top.dockablePanel.getX() + 1; - newResizeRect.y = resizePos + top.buttonPanel.getHeight() + 1; - newResizeRect.width = top.dockablePanel.getWidth() - 2; - } - else if(resizing == left) - { - resizePos = Math.min(resizePos,getWidth() - - left.buttonPanel.getWidth() - - right.dockablePanel.getWidth() - - right.buttonPanel.getWidth() - - PanelWindowContainer.SPLITTER_WIDTH); - newResizeRect.x = resizePos + left.buttonPanel.getWidth() + 1; - newResizeRect.y = left.dockablePanel.getY() + 1; - newResizeRect.height = left.dockablePanel.getHeight() - 2; - } - else if(resizing == bottom) - { - resizePos = Math.min(resizePos,getHeight() - - bottom.buttonPanel.getHeight() - - top.dockablePanel.getHeight() - - top.buttonPanel.getHeight() - - PanelWindowContainer.SPLITTER_WIDTH); - newResizeRect.x = bottom.dockablePanel.getX() + 1; - newResizeRect.y = getHeight() - bottom.buttonPanel.getHeight() - resizePos - - PanelWindowContainer.SPLITTER_WIDTH + 2; - newResizeRect.width = bottom.dockablePanel.getWidth() - 2; - } - else if(resizing == right) - { - resizePos = Math.min(resizePos,getWidth() - - right.buttonPanel.getWidth() - - left.dockablePanel.getWidth() - - left.buttonPanel.getWidth() - - PanelWindowContainer.SPLITTER_WIDTH); - newResizeRect.x = getWidth() - right.buttonPanel.getWidth() - resizePos - - PanelWindowContainer.SPLITTER_WIDTH + 1; - newResizeRect.y = right.dockablePanel.getY() + 1; - newResizeRect.height = right.dockablePanel.getHeight() - 2; - } - - Rectangle toRepaint; - if(resizeRect == null) - toRepaint = newResizeRect; - else - toRepaint = resizeRect.union(newResizeRect); - resizeRect = newResizeRect; - repaint(toRepaint); - } //}}} - - //{{{ finishResizing() method - void finishResizing() - { - resizeRect = null; - repaint(); - } //}}} - - //}}} - - //{{{ propertiesChanged() method - private void propertiesChanged() - { - if(view.isPlainView()) - return; - - ((DockableLayout)getLayout()).setAlternateLayout( - jEdit.getBooleanProperty("view.docking.alternateLayout")); - - String[] windowList = factory.getRegisteredDockableWindows(); - - for(int i = 0; i < windowList.length; i++) - { - String dockable = windowList[i]; - Entry entry = windows.get(dockable); - - String newPosition = jEdit.getProperty(dockable - + ".dock-position",FLOATING); - if(newPosition.equals(entry.position)) - { - continue; - } - - entry.position = newPosition; - if(entry.container != null) - { - entry.container.unregister(entry); - entry.container = null; - if (entry.factory.movable) - { - if (entry.win instanceof DockableWindow) - ((DockableWindow)entry.win).move(newPosition); - } else - entry.win = null; + current.put(keyStroke,action); } - - if(newPosition.equals(FLOATING)) - { - } - - else - { - if(newPosition.equals(TOP)) - entry.container = top; - else if(newPosition.equals(LEFT)) - entry.container = left; - else if(newPosition.equals(BOTTOM)) - entry.container = bottom; - else if(newPosition.equals(RIGHT)) - entry.container = right; - else - { - Log.log(Log.WARNING,this, - "Unknown position: " - + newPosition); - continue; - } - - entry.container.register(entry); - } - } - - top.sortDockables(); - left.sortDockables(); - bottom.sortDockables(); - right.sortDockables(); - - continuousLayout = jEdit.getBooleanProperty("appearance.continuousLayout"); - revalidate(); - repaint(); - } //}}} - - //{{{ addEntry() method - private void addEntry(DockableWindowFactory.Window factory) - { - Entry e; - if(view.isPlainView()) - { - // don't show menu items to dock into a plain view - e = new Entry(factory,FLOATING); - } - else - { - e = new Entry(factory); - if(e.position.equals(FLOATING)) - /* nothing to do */; - else if(e.position.equals(TOP)) - e.container = top; - else if(e.position.equals(LEFT)) - e.container = left; - else if(e.position.equals(BOTTOM)) - e.container = bottom; - else if(e.position.equals(RIGHT)) - e.container = right; - else - { - Log.log(Log.WARNING,this, - "Unknown position: " - + e.position); - } - - if(e.container != null) - e.container.register(e); - } - windows.put(factory.name,e); - } //}}} - - //{{{ getAllPluginEntries() method - /** - * If remove is false, only remove from clones list, otherwise remove - * from both entries and clones. - */ - private Iterator<Entry> getAllPluginEntries(PluginJAR plugin, boolean remove) - { - List<Entry> returnValue = new LinkedList<Entry>(); - Iterator<Entry> iter = windows.values().iterator(); - while(iter.hasNext()) - { - Entry entry = iter.next(); - if(entry.factory.plugin == plugin) - { - returnValue.add(entry); - if(remove) - iter.remove(); - } - } - - iter = clones.iterator(); - while(iter.hasNext()) - { - Entry entry = iter.next(); - if(entry.factory.plugin == plugin) - { - returnValue.add(entry); - iter.remove(); - } - } - - return returnValue.iterator(); - } //}}} - - private boolean continuousLayout; - - //{{{ Entry class - cla... [truncated message content] |