View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.gui.prefs;
21  
22  import java.awt.Dimension;
23  import java.awt.GridBagLayout;
24  import java.util.Hashtable;
25  
26  import javax.help.CSH;
27  import javax.swing.JCheckBox;
28  import javax.swing.JRadioButton;
29  import javax.swing.JScrollPane;
30  import javax.swing.KeyStroke;
31  import javax.swing.ListSelectionModel;
32  import javax.swing.event.ChangeEvent;
33  import javax.swing.event.ChangeListener;
34  import javax.swing.event.TreeSelectionEvent;
35  import javax.swing.event.TreeSelectionListener;
36  
37  import org.xnap.XNap;
38  import org.xnap.gui.AbstractSettingsPanel;
39  import org.xnap.gui.action.EnableAction;
40  import org.xnap.gui.component.KeyStrokePanel;
41  import org.xnap.gui.component.ValidatedTextField;
42  import org.xnap.gui.shortcut.Shortcut;
43  import org.xnap.gui.shortcut.ShortcutManager;
44  import org.xnap.gui.table.Column;
45  import org.xnap.gui.table.DefaultColumnTreeTableModel;
46  import org.xnap.gui.table.DefaultTreeTableNode;
47  import org.xnap.gui.table.JTreeTable;
48  import org.xnap.gui.table.LeafTreeTableNode;
49  import org.xnap.gui.table.TreeTableModel;
50  import org.xnap.gui.tree.StringTreeCellRenderer;
51  import org.xnap.gui.util.GUIHelper;
52  import org.xnap.gui.util.GridBagHelper;
53  
54  /***
55   * Provides controls for shortcut appearance settings.
56   */
57  public class ShortcutPrefsPanel extends AbstractSettingsPanel 
58      implements TreeSelectionListener, ChangeListener
59  {
60      
61      //--- Data field(s) ---
62  
63      private JCheckBox jcShowIcons;
64      private JCheckBox jcShowSplash;
65      private JCheckBox jcShowTooltips;
66      private JCheckBox jcbUseSubMenuForPluginMenus;
67  
68      private ValidatedTextField jteMaxConsoleLines;
69      private ValidatedTextField jteHistorySize;
70  
71      private JRadioButton jrbFocusAlways;
72      private JRadioButton jrbFocusNever;
73      private ShortcutTableModel tm;
74      private KeyStrokePanel shortcutPanel;
75      private ShortcutNode currentNode;
76  	
77      //--- Constructor(s) ---
78  
79      public ShortcutPrefsPanel()
80      {
81  		setLayout(new GridBagLayout());
82  
83  		// help
84  		CSH.setHelpIDString(this, "shortcuts");
85  
86  		tm = new ShortcutTableModel();
87  		JTreeTable shortcutTable = tm.createTreeTable(prefs, "shortcut");
88  		shortcutTable.setPreferredScrollableViewportSize(new Dimension(50, 50));	
89  		shortcutTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
90  		shortcutTable.getTree().getSelectionModel().addTreeSelectionListener(this);
91  		shortcutTable.getTree().setCellRenderer(new StringTreeCellRenderer(tm));
92  		shortcutTable.getTableHeader().setReorderingAllowed(false);
93  
94  		// add shortcuts
95  		Shortcut[] shortcuts = ShortcutManager.getInstance().getShortcuts();
96  		if (shortcuts != null) {
97  			for (int i = 0; i < shortcuts.length; i++) {
98  				tm.add(shortcuts[i]);
99  			}
100 		}
101 
102 		GUIHelper.expandAllNodes(shortcutTable.getTree());
103 
104 		GridBagHelper.addPanel(this, new JScrollPane(shortcutTable));
105 
106 		shortcutPanel = new KeyStrokePanel();
107 		shortcutPanel.addChangeListener(this);
108 		setBorder(GUIHelper.createDefaultBorder(XNap.tr("Shortcut")));
109 		// disable by default, will be enabled when a node is selected
110 		EnableAction.setComponentEnabled(shortcutPanel, false);
111 		GridBagHelper.add(this, shortcutPanel);
112 		GUIHelper.setMnemonics(this);
113     }
114 
115     public void apply() 
116     {
117 		if (currentNode != null) {
118 			currentNode.setKeyStroke(shortcutPanel.getKeyStroke());
119 		}
120 
121 		// traverse tree and commit all shortcuts
122     	for (int i = tm.getChildCount(tm.getRoot()) - 1; i >= 0; i--) {
123 			DefaultTreeTableNode node
124 				= (DefaultTreeTableNode)tm.getChild(tm.getRoot(), i);
125 			for (int j = node.getChildCount() - 1; j >= 0; j--) {
126 				ShortcutNode child = (ShortcutNode)node.getChildAt(j);
127 				child.getShortcut().setKeyStroke(child.getKeyStroke());
128 			}
129     	}
130     }
131 
132     public String getTitle()
133     {
134 		return XNap.tr("Shortcuts");
135     }
136 
137     public void valueChanged(TreeSelectionEvent event) 
138     {
139 		if (currentNode != null) {
140 			currentNode.setKeyStroke(shortcutPanel.getKeyStroke());
141 		}
142 		
143 		Object o = event.getPath().getLastPathComponent();
144 		if (o instanceof ShortcutNode) {
145 			currentNode = (ShortcutNode)o;
146 			shortcutPanel.setKeyStroke(currentNode.getKeyStroke());
147 			shortcutPanel.setDefaultKeyStroke
148 				(currentNode.getShortcut().getDefaultKeyStroke());
149 			EnableAction.setComponentEnabled(shortcutPanel, true);
150 		}
151 		else {
152 			currentNode = null;
153 			shortcutPanel.setKeyStroke(null);
154 			shortcutPanel.setDefaultKeyStroke(null);
155 			EnableAction.setComponentEnabled(shortcutPanel, false);
156 		}
157     }
158 
159 
160 	/***
161 	 *  @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
162 	 */
163 	public void stateChanged(ChangeEvent e)
164 	{
165 		if (currentNode != null) {
166 			currentNode.setKeyStroke(shortcutPanel.getKeyStroke());
167 			tm.changed(currentNode);
168 		}
169 	}
170 
171     private class ShortcutNode extends LeafTreeTableNode {
172 
173 		private KeyStroke stroke;
174 
175 		public ShortcutNode(Shortcut shortcut)
176 		{
177 			super(shortcut);
178 			
179 			this.stroke = shortcut.getKeyStroke();
180 		}
181 		
182 		public void setKeyStroke(KeyStroke keyStroke) 
183 		{
184 			this.stroke = keyStroke;
185 		}
186 
187 		public KeyStroke getKeyStroke()
188 		{
189 			return stroke;
190 		}
191 
192 		public Shortcut getShortcut()
193 		{
194 			return (Shortcut)getData();
195 		}
196 
197     }
198 
199     private class ShortcutTableModel extends DefaultColumnTreeTableModel {
200 
201 		private Hashtable nodeByCategory = new Hashtable();
202 
203 		public ShortcutTableModel()
204 		{
205 			Column columns[] = new Column[] {
206 				new Column("Action", TreeTableModel.class),
207 				//new Column("Scope", String.class),
208 				new Column("Shortcut", String.class),
209 			};
210 			addColumns(columns);
211 		}
212 
213 		public void add(Shortcut shortcut)
214 		{
215 			DefaultTreeTableNode node = (DefaultTreeTableNode)
216 				nodeByCategory.get(shortcut.getCategory());
217 			if (node == null) {
218 				node = new DefaultTreeTableNode(this, shortcut.getCategory());
219 				nodeByCategory.put(shortcut.getCategory(), node);
220 				add(node);
221 			}
222 			node.add(new ShortcutNode(shortcut));
223 		}
224 
225 		public void changed(ShortcutNode node)
226 		{
227 			DefaultTreeTableNode parent = (DefaultTreeTableNode)
228 				nodeByCategory.get(node.getShortcut().getCategory());
229 			if (parent != null) {
230 				parent.changedChildAt(parent.getIndexOfChildByData(node.getData())); 
231 			}
232 		}
233 
234 		public Object getValueAt(Object node, int column)
235 		{
236 			if (node instanceof DefaultTreeTableNode) {
237 				if (column == 0) {
238 					return ((DefaultTreeTableNode)node).getData();
239 				}
240 			}
241 			else if (node instanceof ShortcutNode) {
242 				ShortcutNode sn = (ShortcutNode)node;
243 				switch (column) {
244 				case 0:
245 					return sn.getShortcut().getDescription();
246 				case 1:
247 					return (sn.getKeyStroke() != null) 
248 						? KeyStrokePanel.toString(sn.getKeyStroke())
249 						: null;
250 				}
251 			}
252 
253 			return null;
254 		}
255 
256     }
257 
258 }