1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.gui.plugin;
21
22 import java.awt.BorderLayout;
23 import java.awt.FlowLayout;
24 import java.awt.Font;
25 import java.awt.GridBagLayout;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.ActionListener;
28 import java.util.Enumeration;
29
30 import javax.swing.AbstractAction;
31 import javax.swing.Action;
32 import javax.swing.JCheckBox;
33 import javax.swing.JLabel;
34 import javax.swing.JPanel;
35 import javax.swing.JScrollPane;
36 import javax.swing.JSplitPane;
37 import javax.swing.event.TreeSelectionEvent;
38 import javax.swing.event.TreeSelectionListener;
39
40 import org.xnap.XNap;
41 import org.xnap.gui.component.ProgressDialog;
42 import org.xnap.gui.component.XNapButton;
43 import org.xnap.gui.event.DoubleClickListener;
44 import org.xnap.gui.util.GUIHelper;
45 import org.xnap.gui.util.GridBagHelper;
46 import org.xnap.pkg.PackageInfo;
47 import org.xnap.pkg.XNapPackageManager;
48 import org.xnap.plugin.PluginInfo;
49 import org.xnap.plugin.PluginManager;
50
51 public class PluginPanel extends JPanel
52 implements ActionListener, TreeSelectionListener {
53
54
55
56
57
58 private PluginTree pluginTree;
59 private JCheckBox installCheckBox;
60 private JCheckBox updateCheckBox;
61 private JCheckBox removeCheckBox;
62 private JLabel authorsLabel;
63 private JLabel descriptionLabel;
64 private JLabel longDescriptionLabel;
65 private JLabel nameLabel;
66 private JPanel infoPanel;
67 private JLabel statusLabel;
68 private PluginNode node;
69 private JPanel buttonsPanel;
70
71 private Action acDisable = new DisablePluginAction();
72 private Action acEnable = new EnablePluginAction();
73 private Action detailsAction = new DetailsAction();
74
75
76
77 public PluginPanel(boolean showButtons)
78 {
79
80 pluginTree = new PluginTree();
81 pluginTree.setCellRenderer(new PluginTreeCellRenderer());
82 pluginTree.addTreeSelectionListener(this);
83 DoubleClickListener.install(pluginTree, new DoubleClickAction());
84
85
86 infoPanel = new JPanel();
87 infoPanel.setLayout(new GridBagLayout());
88
89 nameLabel = GridBagHelper.addLabel(infoPanel, "", true);
90 nameLabel.setFont(nameLabel.getFont().deriveFont(Font.BOLD));
91
92 descriptionLabel = new JLabel();
93 GridBagHelper.add(infoPanel, descriptionLabel);
94
95 longDescriptionLabel = new JLabel();
96 GridBagHelper.add(infoPanel, longDescriptionLabel);
97
98 GridBagHelper.addVerticalSpacer(infoPanel);
99
100
101 JPanel actionsPanel = new JPanel(new GridBagLayout());
102 actionsPanel.setBorder
103 (GUIHelper.createDefaultBorder(XNap.tr("Action")));
104 GridBagHelper.add(infoPanel, actionsPanel);
105
106 installCheckBox = new JCheckBox(XNap.tr("Install"));
107 installCheckBox.addActionListener(this);
108 GridBagHelper.add(actionsPanel, installCheckBox);
109
110 updateCheckBox = new JCheckBox(XNap.tr("Update"));
111 updateCheckBox.addActionListener(this);
112 GridBagHelper.add(actionsPanel, updateCheckBox);
113
114 removeCheckBox = new JCheckBox(XNap.tr("Remove"));
115
116
117
118 buttonsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
119 GridBagHelper.add(infoPanel, buttonsPanel);
120
121 buttonsPanel.add(new XNapButton(detailsAction));
122 if (showButtons) {
123 buttonsPanel.add(new XNapButton(acEnable));
124 buttonsPanel.add(new XNapButton(acDisable));
125 }
126
127
128 JLabel statusLabel = new JLabel("");
129
130
131 JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
132 jsp.setDividerSize(2);
133 jsp.setDividerLocation(200);
134 jsp.setBorder(GUIHelper.createEmptyBorder());
135 jsp.add(new JScrollPane(pluginTree,
136 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
137 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),
138 JSplitPane.LEFT);
139 jsp.add(new JScrollPane(infoPanel), JSplitPane.RIGHT);
140
141
142 setLayout(new BorderLayout());
143 add(jsp, BorderLayout.CENTER);
144 add(statusLabel, BorderLayout.SOUTH);
145
146
147 valueChanged();
148 }
149
150
151
152 /***
153 * Invoked when one of the action buttons was selected.
154 */
155 public void actionPerformed(ActionEvent event)
156 {
157 if (installCheckBox.isSelected() || updateCheckBox.isSelected()) {
158 node.setAction("install");
159 }
160 else {
161 node.setAction("purge");
162 }
163 }
164
165
166 /***
167 * Sets the selected actions for all packages.
168 */
169 public void apply()
170 {
171 Enumeration it = pluginTree.getRoot().depthFirstEnumeration();
172 while (it.hasMoreElements()) {
173 Object o = it.nextElement();
174 if (o instanceof PluginNode) {
175 PluginNode node = (PluginNode)o;
176 node.getPackageInfo().setAction(node.getAction());
177 }
178 }
179 }
180
181 public JPanel getButtonPanel()
182 {
183 return buttonsPanel;
184 }
185
186 public PluginTree getPluginTree()
187 {
188 return pluginTree;
189 }
190
191 /***
192 * Returns the currently selected plugin or null if no plugin is selected.
193 */
194 public PluginInfo getSelectedPlugin()
195 {
196 PluginNode node = pluginTree.getSelectedNode();
197 return (node != null) ? node.getPluginInfo() : null;
198 }
199
200 /***
201 * Updates the info panel.
202 */
203 public void setNode(PluginNode node)
204 {
205 this.node = node;
206
207 PackageInfo info = node.getPackageInfo();
208 nameLabel.setText(info.getName() + " " + info.getVersion());
209 descriptionLabel.setText(info.getDescription());
210 longDescriptionLabel.setText(GUIHelper.tt(info.getLongDescription()));
211
212 installCheckBox.setEnabled(!info.isInstalled());
213
214 updateCheckBox.setEnabled(node.isUpdateAvailable());
215
216 installCheckBox.setSelected(!info.isInstalled()
217 && "install".equals(node.getAction()));
218 updateCheckBox.setSelected(node.isUpdateAvailable()
219 && "install".equals(node.getAction()));
220
221 PluginInfo pluginInfo = node.getPluginInfo();
222 if (pluginInfo != null && pluginInfo.isPlugin()) {
223 acEnable.setEnabled(!pluginInfo.isEnabled());
224 acDisable.setEnabled(pluginInfo.isEnabled());
225 }
226 else {
227 acEnable.setEnabled(false);
228 acDisable.setEnabled(false);
229 }
230 }
231
232 public void setStatus(String status)
233 {
234 statusLabel.setText(status);
235 }
236
237 /***
238 * Updates the plugin tree.
239 */
240 public void update()
241 {
242 PluginManager.getInstance().updateFromPackageManager();
243 pluginTree.update();
244 }
245
246 /***
247 * Updates the list of packages and invokes {@link #update()}.
248 *
249 * @see XNapPackageManager.update(ProgressMonitor)
250 */
251 public void updatePackageManager()
252 {
253 ProgressDialog dialog
254 = new ProgressDialog(XNap.tr("Updating packages"));
255 XNapPackageManager.getInstance().update(dialog);
256 dialog.show(this);
257
258 update();
259 XNapPackageManager.getInstance().write();
260 }
261
262 /***
263 * Updates the plugin info panel.
264 */
265 public void valueChanged(TreeSelectionEvent e)
266 {
267 PluginNode node = pluginTree.getSelectedNode();
268 if (node != null) {
269 setNode(node);
270 }
271 infoPanel.setVisible(node != null);
272 }
273
274 public void valueChanged()
275 {
276 valueChanged(null);
277 }
278
279
280
281 private class DoubleClickAction implements ActionListener {
282
283 public void actionPerformed(ActionEvent event)
284 {
285 if (acEnable.isEnabled()) {
286 acEnable.actionPerformed(event);
287 }
288 else if (acDisable.isEnabled()) {
289 acDisable.actionPerformed(event);
290 }
291 }
292
293 }
294
295 private class DetailsAction extends AbstractAction
296 {
297
298 public DetailsAction()
299 {
300 putValue(Action.NAME, XNap.tr("Details"));
301 putValue(Action.SHORT_DESCRIPTION,
302 XNap.tr("Shows a dialog with detailed information about the plugin."));
303 }
304
305
306
307 public void actionPerformed(ActionEvent event)
308 {
309 PluginInfo info = getSelectedPlugin();
310 if (info != null) {
311 PluginDetailsDialog dialog = new PluginDetailsDialog(info);
312 dialog.setLocationRelativeTo(PluginPanel.this);
313 dialog.setVisible(true);
314 }
315 }
316 }
317
318 private class EnablePluginAction extends AbstractAction
319 {
320
321 public EnablePluginAction()
322 {
323 putValue(Action.NAME, XNap.tr("Enable"));
324 putValue(Action.SHORT_DESCRIPTION,
325 XNap.tr("Enables the plugin."));
326 }
327
328
329
330 public void actionPerformed(ActionEvent event)
331 {
332 PluginInfo info = getSelectedPlugin();
333 if (info != null) {
334 if (PluginHelper.enablePlugin(PluginPanel.this, info)) {
335 valueChanged();
336 pluginTree.selectedNodeChanged();
337 }
338 }
339 }
340 }
341
342 private class DisablePluginAction extends AbstractAction
343 {
344
345 public DisablePluginAction()
346 {
347 putValue(Action.NAME, XNap.tr("Disable"));
348 putValue(Action.SHORT_DESCRIPTION,
349 XNap.tr("Disables the plugin."));
350 }
351
352
353
354 public void actionPerformed(ActionEvent event)
355 {
356 PluginInfo info = getSelectedPlugin();
357 if (info != null) {
358 if (PluginHelper.disablePlugin(PluginPanel.this, info)) {
359 valueChanged();
360 pluginTree.selectedNodeChanged();
361 }
362 }
363 }
364
365 }
366
367 }