PageRenderTime 352ms CodeModel.GetById 48ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/bundles/plugins-trunk/InfoViewer/infoviewer/actions/InfoViewerAction.java

#
Java | 305 lines | 197 code | 36 blank | 72 comment | 48 complexity | a2c90f1e1b282d928363649da2a7a0bb MD5 | raw file
  1/*
  2 * InfoViewerAction.java - jEdit action listener
  3 * Copyright (C) 2000-2002 Dirk Moebius
  4 * Contains portions of EditAction.java Copyright (C) 1998, 1999 by
  5 * Slava Pestov
  6 *
  7 * :tabSize=4:indentSize=4:noTabs=true:maxLineLen=0:
  8 *
  9 * This program is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU General Public License
 11 * as published by the Free Software Foundation; either version 2
 12 * of the License, or any later version.
 13 *
 14 * This program is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 * GNU General Public License for more details.
 18 *
 19 * You should have received a copy of the GNU General Public License
 20 * along with this program; if not, write to the Free Software
 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 22 */
 23
 24package infoviewer.actions;
 25
 26import infoviewer.InfoViewer;
 27
 28import java.awt.Component;
 29import java.awt.Frame;
 30import java.awt.event.InputEvent;
 31import java.awt.event.KeyEvent;
 32import java.beans.PropertyChangeListener;
 33import java.util.EventObject;
 34
 35import javax.swing.AbstractAction;
 36import javax.swing.Action;
 37import javax.swing.ButtonModel;
 38import javax.swing.Icon;
 39import javax.swing.JButton;
 40import javax.swing.JCheckBoxMenuItem;
 41import javax.swing.JMenu;
 42import javax.swing.JMenuItem;
 43import javax.swing.JPopupMenu;
 44import javax.swing.JToggleButton;
 45import javax.swing.KeyStroke;
 46import javax.swing.JToggleButton.ToggleButtonModel;
 47import javax.swing.event.ChangeEvent;
 48import javax.swing.event.ChangeListener;
 49
 50import org.gjt.sp.jedit.GUIUtilities;
 51import org.gjt.sp.jedit.jEdit;
 52import org.gjt.sp.jedit.gui.DefaultInputHandler;
 53import org.gjt.sp.jedit.gui.KeyEventTranslator;
 54import org.gjt.sp.util.Log;
 55
 56
 57
 58/**
 59 * The class all InfoViewer actions must extend. It is an
 60 * <code>AbstractAction</code> with support for finding out the InfoViewer
 61 * that invoked the action.
 62 * <p>
 63 * 
 64 * @author Dirk Moebius
 65 */
 66public abstract class InfoViewerAction extends AbstractAction 
 67{
 68	/** Base name for properties */
 69	String name;
 70
 71	JToggleButton.ToggleButtonModel toggleModel;
 72	
 73	
 74	// {{{ isToggle() method
 75	/**
 76	 * Returns if this edit action should be displayed as a check box in
 77	 * menus. This returns the value of the property named by
 78	 * {@link #getName()} suffixed with <code>.toggle</code>.
 79	 * 
 80	 * @since jEdit 2.2pre4
 81	 */
 82	public boolean isToggle()
 83	{
 84		return jEdit.getBooleanProperty(name + ".toggle");
 85	} // }}}
 86
 87	
 88	/* public void setSelected(boolean selected) {
 89		toggleModel.setSelected(selected);
 90		// jEdit.setBooleanProperty(name + ".selected", selected);
 91	}
 92	*/
 93	public boolean isSelected()
 94	{
 95		return toggleModel.isSelected();
 96//		return jEdit.getBooleanProperty(name + ".selected");
 97	}
 98
 99	public JMenuItem menuItem() 
100	{
101		JMenuItem retval = null;
102		if (isToggle()) 
103		{
104
105			JCheckBoxMenuItem cmi = new JCheckBoxMenuItem(this);
106			cmi.setModel(toggleModel);
107			retval = cmi;
108		}
109		else 
110		{
111			retval = new JMenuItem(this);
112		}
113		return retval;
114	}
115
116	public static KeyStroke parseKeyStroke(String keyStroke)
117	{
118		if (keyStroke == null)
119			return null;
120		int modifiers = 0;
121		int index = keyStroke.indexOf('+');
122		if (index != -1)
123		{
124			for (int i = 0; i < index; i++)
125			{
126				switch (Character.toUpperCase(keyStroke.charAt(i)))
127				{
128				case 'A':
129					modifiers |= InputEvent.ALT_MASK;
130					break;
131				case 'C':
132					modifiers |= InputEvent.CTRL_MASK;
133					break;
134				case 'M':
135					modifiers |= InputEvent.META_MASK;
136					break;
137				case 'S':
138					modifiers |= InputEvent.SHIFT_MASK;
139					break;
140				}
141			}
142		}
143		String key = keyStroke.substring(index + 1);
144		if (key.length() == 1)
145		{
146			char ch = key.charAt(0);
147			if (modifiers == 0)
148				return KeyStroke.getKeyStroke(ch);
149			else
150			{
151				return KeyStroke.getKeyStroke(Character.toUpperCase(ch), modifiers);
152			}
153		}
154		else if (key.length() == 0)
155		{
156			Log.log(Log.ERROR, DefaultInputHandler.class, "Invalid key stroke: "
157				+ keyStroke);
158			return null;
159		}
160		else
161		{
162			int ch;
163
164			try
165			{
166				ch = KeyEvent.class.getField("VK_".concat(key)).getInt(null);
167			}
168			catch (Exception e)
169			{
170				Log.log(Log.ERROR, DefaultInputHandler.class,
171					"Invalid key stroke: " + keyStroke);
172				return null;
173			}
174
175			return KeyStroke.getKeyStroke(ch, modifiers);
176		}
177	}
178
179	/**
180	 * Creates a new <code>InfoViewerAction</code>. This constructor
181	 * should be used by InfoViewer's own actions only.
182	 * 
183	 * @param name_key
184	 *                a jEdit property with the name for the action. Other
185	 *                resources are determined by looking up the following
186	 *                keys in the jEdit properties:
187	 *                <ul>
188	 *                <li><code>name.icon</code> the icon filename</li>
189	 *                <li><code>name.description</code> a short
190	 *                description</li>
191	 *                <li><code>name.mnemonic</code> a menu mnemonic</li>
192	 *                <li><code>name.shortcut</code> an keybord shortcut</li>
193	 *                </ul>
194	 * @see java.awt.KeyStroke#getKeyStroke
195	 */
196	InfoViewerAction(String name_key)
197	{
198		super(jEdit.getProperty(name_key));
199		name = name_key;
200
201		if (isToggle()) { 
202			toggleModel = new ToggleButtonModel();
203			toggleModel.setSelected(true);
204		}
205		
206		String icon = jEdit.getProperty(name_key + ".icon");
207		String desc = jEdit.getProperty(name_key + ".description");
208		String mnem = jEdit.getProperty(name_key + ".mnemonic");
209		String shrt = jEdit.getProperty(name_key + ".shortcut");
210		String label =  jEdit.getProperty(name_key + ".label") ;
211
212		
213		
214		if (icon != null)
215		{
216			Icon i = GUIUtilities.loadIcon(icon);
217			if (i != null)
218				putValue(SMALL_ICON, i);
219		}
220
221		if (desc != null)
222		{
223			putValue(SHORT_DESCRIPTION, desc);
224			putValue(LONG_DESCRIPTION, desc);
225		}
226
227		if (label != null) {
228			putValue(NAME, label);
229		}
230		
231		if (mnem != null)
232			putValue(MNEMONIC_KEY, new Integer(mnem.charAt(0)));
233
234		if (shrt != null)
235		{
236			KeyStroke keyStroke = parseKeyStroke(shrt);
237			putValue(ACCELERATOR_KEY, keyStroke);
238		}
239	}
240
241	/**
242	 * Determines the InfoViewer to use for the action.
243	 */
244	public static InfoViewer getViewer(EventObject evt)
245	{
246		if (evt == null)
247			return null; // this shouldn't happen
248
249		Object o = evt.getSource();
250		if (o instanceof Component)
251			return getViewer((Component) o);
252		else
253			return null;
254	}
255
256	/**
257	 * Finds the InfoViewer parent of the specified component.
258	 */
259	public static InfoViewer getViewer(Component comp)
260	{
261		for (;;)
262		{
263			if (comp instanceof InfoViewer)
264				return (InfoViewer) comp;
265			else if (comp instanceof JPopupMenu)
266				comp = ((JPopupMenu) comp).getInvoker();
267			else if (comp != null)
268				comp = comp.getParent();
269			else
270				break;
271		}
272		return null;
273	}
274
275	/**
276	 * Finds the Frame parent of the source component of the given
277	 * EventObject.
278	 */
279	public static Frame getFrame(EventObject evt)
280	{
281		if (evt == null)
282			return null; // this shouldn't happen
283
284		Object source = evt.getSource();
285
286		if (source instanceof Component)
287		{
288			Component comp = (Component) source;
289			for (;;)
290			{
291				if (comp instanceof Frame)
292					return (Frame) comp;
293				else if (comp instanceof JPopupMenu)
294					comp = ((JPopupMenu) comp).getInvoker();
295				else if (comp != null)
296					comp = comp.getParent();
297				else
298					break;
299			}
300		}
301
302		return null;
303	}
304
305}