source: AE/installer2/src/net/oni2/aeinstaller/gui/modtable/ModTable.java@ 657

Last change on this file since 657 was 657, checked in by alloc, 12 years ago

AEI2 0.99i:

  • Added (un)select all button
  • Fixed install in offline mode
  • Added entry in mod-table-context menu to delete local package
  • Added "added" column to mod table
File size: 10.1 KB
Line 
1package net.oni2.aeinstaller.gui.modtable;
2
3import java.awt.Desktop;
4import java.awt.Rectangle;
5import java.awt.event.ActionEvent;
6import java.awt.event.ActionListener;
7import java.awt.event.KeyAdapter;
8import java.awt.event.KeyEvent;
9import java.awt.event.MouseAdapter;
10import java.awt.event.MouseEvent;
11import java.io.File;
12import java.io.IOException;
13import java.util.ArrayList;
14import java.util.HashSet;
15import java.util.List;
16import java.util.ResourceBundle;
17import java.util.TreeSet;
18
19import javax.swing.JComponent;
20import javax.swing.JMenuItem;
21import javax.swing.JOptionPane;
22import javax.swing.JPopupMenu;
23import javax.swing.JTable;
24import javax.swing.JViewport;
25import javax.swing.ListSelectionModel;
26import javax.swing.RowSorter;
27import javax.swing.SortOrder;
28import javax.swing.event.ListSelectionEvent;
29import javax.swing.event.RowSorterEvent;
30import javax.swing.table.TableRowSorter;
31
32import net.oni2.aeinstaller.backend.Settings;
33import net.oni2.aeinstaller.backend.packages.Package;
34import net.oni2.aeinstaller.backend.packages.Type;
35
36/**
37 * @author Christian Illy
38 */
39public class ModTable extends JTable {
40 private static final long serialVersionUID = 1L;
41
42 private ResourceBundle bundle = ResourceBundle
43 .getBundle("net.oni2.aeinstaller.localization.ModTable");
44
45 /**
46 * @author Christian Illy
47 */
48 public enum ETableContentType {
49 /**
50 * Table showing mods
51 */
52 MODS,
53 /**
54 * Table showing tools
55 */
56 TOOLS,
57 /**
58 * Table showing core packages
59 */
60 CORE
61 };
62
63 private HashSet<ModSelectionListener> modSelListeners = new HashSet<ModSelectionListener>();
64
65 private ModTableModel model;
66 private TableRowSorter<ModTableModel> sorter;
67
68 private ETableContentType contentType = ETableContentType.MODS;
69
70 /**
71 * Create a new ModTable
72 */
73 public ModTable() {
74 super();
75
76 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
77 getSelectionModel().addListSelectionListener(this);
78 addMouseListener(new MouseEventHandler());
79 addKeyListener(new KeyEventHandler());
80 // To get checkbox-cells with background of row
81 ((JComponent) getDefaultRenderer(Boolean.class)).setOpaque(true);
82
83 model = new ModTableModel();
84
85 setModel(model);
86
87 sorter = new TableRowSorter<ModTableModel>(model);
88 setRowSorter(sorter);
89
90 setFilter(null, 0);
91
92 List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
93
94 int sortCol = Settings.getInstance().get("modSortColumn", 1);
95 SortOrder sortOrder = SortOrder.valueOf(Settings.getInstance().get(
96 "modSortOrder", "ASCENDING"));
97
98 sortKeys.add(new RowSorter.SortKey(sortCol, sortOrder));
99 sorter.setSortKeys(sortKeys);
100
101 for (int i = 0; i < model.getColumnCount(); i++) {
102 model.setColumnConstraints(i, getColumnModel().getColumn(i));
103 }
104 }
105
106 @Override
107 public String getToolTipText(MouseEvent e) {
108 int r = rowAtPoint(e.getPoint());
109 int c = columnAtPoint(e.getPoint());
110 if (r >= 0 && r < getRowCount()) {
111 int modelCol = convertColumnIndexToModel(c);
112 if (modelCol == 4) {
113 final Package mod = (Package) getValueAt(r, -1);
114
115 String tt = "<html>";
116 tt += String.format("%s: %s<br>",
117 bundle.getString("state.installed"),
118 bundle.getString((mod.isInstalled() ? "yes" : "no")));
119 tt += String.format(
120 "%s: %s<br>",
121 bundle.getString("state.updatable"),
122 bundle.getString((mod.isLocalAvailable()
123 && mod.isNewerAvailable() ? "yes" : "no")));
124 tt += String.format("%s: %s</html>", bundle
125 .getString("state.downloaded"), bundle.getString((mod
126 .isLocalAvailable() ? "yes" : "no")));
127 return tt;
128 }
129 }
130 return super.getToolTipText(e);
131 }
132
133 /**
134 * @param listener
135 * Listener to add
136 */
137 public void addModSelectionListener(ModSelectionListener listener) {
138 modSelListeners.add(listener);
139 }
140
141 /**
142 * @param listener
143 * Listener to remove
144 */
145 public void removeModSelectionListener(ModSelectionListener listener) {
146 modSelListeners.remove(listener);
147 }
148
149 private void notifyModSelectionListeners(Package m) {
150 for (ModSelectionListener l : modSelListeners) {
151 l.modSelectionChanged(this, m);
152 }
153 }
154
155 /**
156 * @param listener
157 * Listener to add
158 */
159 public void addDownloadSizeListener(DownloadSizeListener listener) {
160 model.addDownloadSizeListener(listener);
161 }
162
163 /**
164 * @param listener
165 * Listener to remove
166 */
167 public void removeDownloadSizeListener(DownloadSizeListener listener) {
168 model.removeDownloadSizeListener(listener);
169 }
170
171 /**
172 * Reload the nodes data after an update to the cache
173 */
174 public void reloadData() {
175 model.reloadData();
176 }
177
178 /**
179 * Revert the selection to the mods that are currently installed
180 */
181 public void revertSelection() {
182 model.revertSelection();
183 }
184
185 /**
186 * Reload the selection after a config was loaded
187 *
188 * @param config
189 * Config to load
190 */
191 public void reloadSelection(File config) {
192 model.reloadSelection(config);
193 }
194
195 /**
196 * @return Mods selected for installation
197 */
198 public TreeSet<Package> getSelectedMods() {
199 return model.getSelectedMods();
200 }
201
202 /**
203 * @param type
204 * Type of mods to show (null for all)
205 * @param downloadState
206 * Show only: 0 = all, 1 = online, 2 = downloaded
207 */
208 public void setFilter(Type type, int downloadState) {
209 sorter.setRowFilter(new ModTableFilter(type, downloadState,
210 contentType == ETableContentType.CORE, false));
211 }
212
213 @Override
214 public void sorterChanged(RowSorterEvent evt) {
215 super.sorterChanged(evt);
216 if (evt.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) {
217 @SuppressWarnings("unchecked")
218 RowSorter<ModTableModel> rs = (RowSorter<ModTableModel>) getRowSorter();
219 List<? extends RowSorter.SortKey> keys = rs.getSortKeys();
220 if (keys.size() > 0) {
221 int col = keys.get(0).getColumn();
222 SortOrder so = keys.get(0).getSortOrder();
223 Settings.getInstance().put("modSortColumn", col);
224 Settings.getInstance().put("modSortOrder", so.toString());
225 }
226 }
227 }
228
229 /**
230 * Select/Unselect all currently visible items depending on the current
231 * state of selection
232 */
233 public void unSelectAll() {
234 boolean isAll = true;
235 for (int i = 0; i < getRowCount(); i++) {
236 int modRow = convertRowIndexToModel(i);
237 boolean inst = (Boolean) model.getValueAt(modRow, 0);
238 if (!inst) {
239 isAll = false;
240 break;
241 }
242 }
243
244 for (int i = 0; i < getRowCount(); i++) {
245 int modRow = convertRowIndexToModel(i);
246 model.setValueAt(!isAll, modRow, 0);
247 }
248 invalidate();
249 repaint();
250 }
251
252 @Override
253 public void valueChanged(ListSelectionEvent e) {
254 super.valueChanged(e);
255 int viewRow = getSelectedRow();
256 if (viewRow < 0) {
257 notifyModSelectionListeners(null);
258 } else {
259 Package mod = (Package) getValueAt(viewRow, -1);
260 notifyModSelectionListeners(mod);
261 }
262 }
263
264 private class MouseEventHandler extends MouseAdapter {
265 private void mouseEventProcessing(MouseEvent e) {
266 int r = rowAtPoint(e.getPoint());
267 if (r >= 0 && r < getRowCount())
268 setRowSelectionInterval(r, r);
269 else
270 clearSelection();
271
272 int rowindex = getSelectedRow();
273 if (rowindex >= 0) {
274 if (e.isPopupTrigger() && e.getComponent() instanceof JTable) {
275 final Package mod = (Package) getValueAt(rowindex, -1);
276
277 JPopupMenu popup = new JPopupMenu();
278
279 if (mod.isLocalAvailable()) {
280 // Open package folder item
281 JMenuItem openModFolder = new JMenuItem(
282 bundle.getString("openModFolder.text"));
283 openModFolder.addActionListener(new ActionListener() {
284 @Override
285 public void actionPerformed(ActionEvent arg0) {
286 try {
287 Desktop.getDesktop().open(
288 mod.getLocalPath());
289 } catch (IOException e) {
290 e.printStackTrace();
291 }
292 }
293 });
294 popup.add(openModFolder);
295 }
296
297 if (mod.getUrl() != null) {
298 // Open Depot page item
299 JMenuItem openDepotPage = new JMenuItem(
300 bundle.getString("openDepotPage.text"));
301 openDepotPage.addActionListener(new ActionListener() {
302 @Override
303 public void actionPerformed(ActionEvent arg0) {
304 try {
305 Desktop.getDesktop().browse(mod.getUrl());
306 } catch (IOException e) {
307 e.printStackTrace();
308 }
309 }
310 });
311 popup.add(openDepotPage);
312 }
313
314 if (mod.isLocalAvailable()
315 && contentType != ETableContentType.CORE) {
316 // Delete package folder item
317 JMenuItem deleteModFolder = new JMenuItem(
318 bundle.getString("deletePackage.text"));
319 deleteModFolder.addActionListener(new ActionListener() {
320 @Override
321 public void actionPerformed(ActionEvent arg0) {
322 if (mod.getNode() == null) {
323 JOptionPane.showMessageDialog(
324 null,
325 bundle.getString("deletePackageLocalOnly.text"),
326 bundle.getString("deletePackageLocalOnly.title"),
327 JOptionPane.INFORMATION_MESSAGE);
328 } else {
329 int res = JOptionPane.showConfirmDialog(
330 null,
331 bundle.getString("deletePackageConfirm.text"),
332 bundle.getString("deletePackageConfirm.title"),
333 JOptionPane.YES_NO_OPTION,
334 JOptionPane.WARNING_MESSAGE);
335 if (res == JOptionPane.YES_OPTION) {
336 mod.deleteLocalPackage();
337 invalidate();
338 repaint();
339 }
340 }
341 }
342 });
343 popup.add(deleteModFolder);
344 }
345
346 if (popup.getSubElements().length > 0)
347 popup.show(e.getComponent(), e.getX(), e.getY());
348 }
349 }
350 }
351
352 @Override
353 public void mousePressed(MouseEvent e) {
354 mouseEventProcessing(e);
355 }
356
357 @Override
358 public void mouseReleased(MouseEvent e) {
359 mouseEventProcessing(e);
360 }
361 }
362
363 private class KeyEventHandler extends KeyAdapter {
364 @Override
365 public void keyTyped(KeyEvent e) {
366 super.keyTyped(e);
367
368 if (e.getModifiers() == 0) {
369 String key = String.valueOf(e.getKeyChar()).toLowerCase();
370 for (int i = 0; i < getRowCount(); i++) {
371 Package m = (Package) getValueAt(i, -1);
372 if (m.getName().toLowerCase().startsWith(key)) {
373 setRowSelectionInterval(i, i);
374 JViewport viewport = (JViewport) getParent();
375 Rectangle rect = getCellRect(i, 0, true);
376 Rectangle r2 = viewport.getVisibleRect();
377 scrollRectToVisible(new Rectangle(rect.x, rect.y,
378 (int) r2.getWidth(), (int) r2.getHeight()));
379 break;
380 }
381 }
382 }
383 }
384 }
385}
Note: See TracBrowser for help on using the repository browser.