1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.xnap.gui.pkg;
20
21 import java.awt.BorderLayout;
22 import java.awt.Component;
23 import java.awt.FlowLayout;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.WindowAdapter;
26 import java.awt.event.WindowEvent;
27
28 import javax.swing.AbstractAction;
29 import javax.swing.Action;
30 import javax.swing.JLabel;
31 import javax.swing.JPanel;
32 import javax.swing.JScrollPane;
33 import javax.swing.JSplitPane;
34 import javax.swing.SwingConstants;
35 import javax.swing.border.EmptyBorder;
36 import javax.swing.event.TreeSelectionEvent;
37 import javax.swing.event.TreeSelectionListener;
38
39 import org.apache.log4j.Logger;
40 import org.xnap.XNap;
41 import org.xnap.gui.Dialogs;
42 import org.xnap.gui.StatusBar;
43 import org.xnap.gui.component.DefaultDialog;
44 import org.xnap.gui.component.ProgressDialog;
45 import org.xnap.gui.component.XNapButton;
46 import org.xnap.pkg.DefaultDependencyParser;
47 import org.xnap.pkg.DefaultResolver;
48 import org.xnap.pkg.DependencyGraph;
49 import org.xnap.pkg.PackageInfo;
50 import org.xnap.pkg.ParseException;
51 import org.xnap.pkg.UnsatisfiedDependenciesException;
52 import org.xnap.pkg.XNapPackageManager;
53
54 public class PackageDialog extends DefaultDialog
55 implements TreeSelectionListener {
56
57
58
59
60
61 private static Logger logger = Logger.getLogger(PackageDialog.class);
62 private static PackageDialog me = null;
63
64 private JLabel jlStatus;
65 private PackageInfoTree jtPackages;
66 private PackageInfoPanel jpInfo;
67 private boolean canClose = true;
68
69 private Action acInstall = new InstallAction();
70 private Action acRemove = new RemoveAction();
71 private Action acShowDepends = new ShowDependsAction();
72 private Action acUpdateList = new UpdateListAction();
73
74
75
76 private PackageDialog()
77 {
78 super(BUTTON_CLOSE);
79
80 StatusBar.setText(XNap.tr("Reading list of packages") + "...");
81 XNapPackageManager.getInstance().initialize();
82 StatusBar.setText("");
83
84 initialize();
85
86 pack();
87 setSize(600, 500);
88
89 jtPackages.updatePackages
90 (XNapPackageManager.getInstance().packages());
91 valueChanged();
92 }
93
94
95
96 private void initialize()
97 {
98 setTitle(XNap.tr("Manage Packages"));
99
100
101 JPanel jpIconInfo = new JPanel(new FlowLayout(FlowLayout.LEFT));
102 jpIconInfo.add(new JLabel(XNap.tr("Available"),
103 PackageInfoCellRenderer.ICON_NOT_INSTALLED,
104 SwingConstants.LEFT));
105 jpIconInfo.add(new JLabel(XNap.tr("Installed"),
106 PackageInfoCellRenderer.ICON_INSTALLED,
107 SwingConstants.LEFT));
108 jpIconInfo.add
109 (new JLabel(XNap.tr("Update Available"),
110 PackageInfoCellRenderer.ICON_UPDATE_AVAILABLE,
111 SwingConstants.LEFT));
112 jpIconInfo.add(new JLabel(XNap.tr("New"),
113 PackageInfoCellRenderer.ICON_NEW,
114 SwingConstants.LEFT));
115
116
117 jlStatus = new JLabel(" ");
118 jlStatus.setBorder(new EmptyBorder(5, 5, 5, 5));
119
120
121 jtPackages = new PackageInfoTree();
122 jtPackages.setCellRenderer(new PackageInfoCellRenderer());
123 jtPackages.addTreeSelectionListener(this);
124
125
126 jpInfo = new PackageInfoPanel();
127
128 jpInfo.getButtonPanel().add(new XNapButton(acInstall));
129 jpInfo.getButtonPanel().add(new XNapButton(acRemove));
130 jpInfo.getButtonPanel().add(new XNapButton(acShowDepends));
131
132
133 JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
134 jsp.setDividerSize(2);
135 jsp.setDividerLocation(180);
136 jsp.add(new JScrollPane(jtPackages), JSplitPane.LEFT);
137 jsp.add(new JScrollPane(jpInfo), JSplitPane.RIGHT);
138
139 getMainPanel().setLayout(new BorderLayout());
140 getMainPanel().add(jpIconInfo, BorderLayout.NORTH);
141 getMainPanel().add(jsp, BorderLayout.CENTER);
142 getMainPanel().add(jlStatus, BorderLayout.SOUTH);
143
144 getButtonPanel().add(new XNapButton(acUpdateList), 1);
145 }
146
147 public static void showDialog(Component c)
148 {
149 if (me == null) {
150 me = new PackageDialog();
151 }
152 me.show(c);
153 }
154
155 public void close()
156 {
157 if (canClose) {
158 dispose();
159 me = null;
160 }
161 }
162
163 private void setStatus(String newValue)
164 {
165 jlStatus.setText(newValue);
166 jlStatus.setToolTipText(newValue);
167 }
168
169 /***
170 * Updates the package info panel.
171 */
172 public void valueChanged(TreeSelectionEvent e)
173 {
174 PackageInfo info = jtPackages.getSelectedInfo();
175 if (info != null) {
176 if (!canClose) {
177 return;
178 }
179
180 jpInfo.setInfo(info);
181 acInstall.setEnabled(!info.isInstalled());
182 acRemove.setEnabled(false);
183 }
184
185 jpInfo.setVisible(info != null);
186 }
187
188 public void valueChanged()
189 {
190 valueChanged(null);
191 }
192
193 private DependencyGraph buildGraph()
194 {
195 DependencyGraph graph
196 = new DependencyGraph(XNapPackageManager.getInstance());
197 graph.add(jtPackages.getSelectedInfo());
198
199 try {
200 graph.buildDependencies(new DefaultDependencyParser());
201 }
202 catch (ParseException e) {
203 Dialogs.error(PackageDialog.this, e.getLocalizedMessage());
204 return null;
205 }
206
207 return graph;
208 }
209
210 /***
211 * Enables or disables all widgets.
212 */
213 public void setDialogEnabled(boolean enabled)
214 {
215 acInstall.setEnabled(enabled);
216 acRemove.setEnabled(enabled);
217
218 canClose = enabled;
219 if (enabled) {
220 valueChanged();
221 }
222 }
223
224
225
226 private class InstallAction extends AbstractAction {
227
228 public InstallAction()
229 {
230 putValue(Action.NAME, XNap.tr("Install") + "...");
231 putValue(Action.SHORT_DESCRIPTION,
232 XNap.tr("Downloads the selected package."));
233 }
234
235 public void actionPerformed(ActionEvent event)
236 {
237 DependencyGraph graph = buildGraph();
238 if (graph != null) {
239 PackageInfo[] packages;
240 try {
241 DefaultResolver r = new DefaultResolver(graph, false);
242 r.resolve();
243 packages = r.getRequiredUninstalled();
244 }
245 catch (UnsatisfiedDependenciesException e) {
246 String message
247 = XNap.tr("Unsatisfied dependency: Missing {0}.",
248 e.getLocalizedMessage());
249 Dialogs.error(PackageDialog.this, message);
250 return;
251 }
252
253 PackageInstallerDialog d
254 PackageInstallerDialog(packages)/package-summary.html">= new PackageInstallerDialog(packages);
255 d.addWindowListener(new DisposeListener());
256 d.show(PackageDialog.this);
257
258 setDialogEnabled(false);
259 }
260 }
261
262 private class DisposeListener extends WindowAdapter
263 {
264
265 public void windowClosed(WindowEvent event)
266 {
267
268 jtPackages.reload();
269 valueChanged(null);
270
271 XNapPackageManager.getInstance().write();
272
273 setDialogEnabled(true);
274 }
275 }
276
277 }
278
279 private class RemoveAction extends AbstractAction {
280
281 public RemoveAction()
282 {
283 putValue(Action.NAME, XNap.tr("Remove") + "...");
284 putValue(Action.SHORT_DESCRIPTION,
285 XNap.tr("Removes the package."));
286 }
287
288 public void actionPerformed(ActionEvent event)
289 {
290 }
291 }
292
293 private class ShowDependsAction extends AbstractAction {
294
295 public ShowDependsAction()
296 {
297 putValue(Action.NAME, XNap.tr("Dependencies") + "...");
298 putValue(Action.SHORT_DESCRIPTION,
299 XNap.tr("Shows the dependency graph."));
300 }
301
302 public void actionPerformed(ActionEvent event)
303 {
304 DependencyGraph graph = buildGraph();
305 if (graph != null) {
306 DependencyGraphDialog d = new DependencyGraphDialog(graph);
307 d.setModal(true);
308 d.show(PackageDialog.this);
309 }
310 }
311 }
312
313 private class UpdateListAction extends AbstractAction {
314
315 public UpdateListAction()
316 {
317 putValue(Action.NAME, XNap.tr("Update List"));
318 putValue(Action.SHORT_DESCRIPTION,
319 XNap.tr("Updates the list packages from the internet."));
320 }
321
322 public void actionPerformed(ActionEvent event)
323 {
324 setStatus(XNap.tr("Getting list of packages") + "...");
325
326 ProgressDialog dialog
327 = new ProgressDialog(XNap.tr("Updating packages"));
328 XNapPackageManager.getInstance().update(dialog);
329 dialog.show(PackageDialog.this);
330
331 int count = XNapPackageManager.getInstance().getPackageCount();
332 setStatus(XNap.tr("{0} packages available", new Integer(count)));
333
334 jtPackages.updatePackages
335 (XNapPackageManager.getInstance().packages());
336 }
337 }
338
339 }