瀏覽代碼

fixes issue 2897

tags/0.6.3m2a1
Gregory Holmes 15 年之前
父節點
當前提交
df9924d8d3

+ 94
- 0
src/com/dmdirc/addons/ui_swing/components/addonbrowser/AddonFilter.java 查看文件

@@ -0,0 +1,94 @@
1
+/*
2
+ * 
3
+ * Copyright (c) 2006-2008 Chris Smith, Shane Mc Cormack, Gregory Holmes
4
+ * 
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ * 
12
+ * The above copyright notice and this permission notice shall be included in
13
+ * all copies or substantial portions of the Software.
14
+ * 
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+
24
+package com.dmdirc.addons.ui_swing.components.addonbrowser;
25
+
26
+import javax.swing.ButtonModel;
27
+import javax.swing.JTextField;
28
+import javax.swing.RowFilter;
29
+import javax.swing.RowFilter.Entry;
30
+import javax.swing.table.DefaultTableModel;
31
+
32
+/**
33
+ * Addon filter.
34
+ */
35
+public class AddonFilter extends RowFilter<DefaultTableModel, Integer> {
36
+
37
+    private ButtonModel verifiedBox;
38
+    private ButtonModel unverifiedBox;
39
+    private ButtonModel installedBox;
40
+    private ButtonModel notinstalledBox;
41
+    private ButtonModel pluginsBox;
42
+    private ButtonModel themesBox;
43
+    private ButtonModel actionsBox;
44
+    private JTextField searchBox;
45
+
46
+    /**
47
+     * Creates a new addon filter.
48
+     * 
49
+     * @param verifiedBox
50
+     * @param unverifiedBox
51
+     * @param installedBox
52
+     * @param notinstalledBox
53
+     * @param pluginsBox
54
+     * @param themesBox
55
+     * @param actionsBox
56
+     * @param searchBox
57
+     */
58
+    public AddonFilter(final ButtonModel verifiedBox,
59
+            final ButtonModel unverifiedBox, final ButtonModel installedBox,
60
+            final ButtonModel notinstalledBox, final ButtonModel pluginsBox,
61
+            final ButtonModel themesBox, final ButtonModel actionsBox,
62
+            final JTextField searchBox) {
63
+        this.verifiedBox = verifiedBox;
64
+        this.unverifiedBox = unverifiedBox;
65
+        this.installedBox = installedBox;
66
+        this.notinstalledBox = notinstalledBox;
67
+        this.pluginsBox = pluginsBox;
68
+        this.themesBox = themesBox;
69
+        this.actionsBox = actionsBox;
70
+        this.searchBox = searchBox;
71
+    }
72
+
73
+    /** {@inheritDoc} */
74
+    @Override
75
+    public boolean include(
76
+            Entry<? extends DefaultTableModel, ? extends Integer> entry) {
77
+        AddonInfo info = ((AddonInfoLabel) entry.getModel().getValueAt(entry.
78
+                getIdentifier(), 0)).getAddonInfo();
79
+        if ((!verifiedBox.isSelected() && info.isVerified()) ||
80
+                (!unverifiedBox.isSelected() && !info.isVerified()) ||
81
+                (!installedBox.isSelected() && info.isInstalled()) ||
82
+                (!notinstalledBox.isSelected() &&
83
+                !info.isInstalled()) || (!pluginsBox.isSelected() &&
84
+                info.getType() == AddonType.TYPE_PLUGIN) ||
85
+                (!themesBox.isSelected() && info.getType() ==
86
+                AddonType.TYPE_THEME) ||
87
+                (!actionsBox.isSelected() && info.getType() ==
88
+                AddonType.TYPE_ACTION_PACK) || (!searchBox.getText().
89
+                isEmpty() && !info.matches(searchBox.getText()))) {
90
+            return false;
91
+        }
92
+        return true;
93
+    }
94
+}

+ 9
- 0
src/com/dmdirc/addons/ui_swing/components/addonbrowser/AddonInfoLabel.java 查看文件

@@ -94,4 +94,13 @@ public class AddonInfoLabel extends JPanel {
94 94
 
95 95
         add(new JSeparator(), "newline, span, growx, pushx, gaptop 5");
96 96
     }
97
+
98
+    /**
99
+     * Returns the addon info for this label.
100
+     *
101
+     * @return Addon info
102
+     */
103
+    public AddonInfo getAddonInfo() {
104
+        return addonInfo;
105
+    }
97 106
 }

+ 85
- 0
src/com/dmdirc/addons/ui_swing/components/addonbrowser/AddonSorter.java 查看文件

@@ -0,0 +1,85 @@
1
+/*
2
+ * 
3
+ * Copyright (c) 2006-2008 Chris Smith, Shane Mc Cormack, Gregory Holmes
4
+ * 
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ * 
12
+ * The above copyright notice and this permission notice shall be included in
13
+ * all copies or substantial portions of the Software.
14
+ * 
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+
24
+package com.dmdirc.addons.ui_swing.components.addonbrowser;
25
+
26
+import java.util.Comparator;
27
+
28
+import javax.swing.ButtonModel;
29
+import javax.swing.table.DefaultTableModel;
30
+import javax.swing.table.TableRowSorter;
31
+
32
+/**
33
+ * Addon sorter.
34
+ */
35
+public class AddonSorter extends TableRowSorter<DefaultTableModel> implements
36
+        Comparator<AddonInfoLabel> {
37
+
38
+    private ButtonModel sortByDate;
39
+    private ButtonModel sortByName;
40
+    private ButtonModel sortByRating;
41
+    private ButtonModel sortByStatus;
42
+
43
+    /**
44
+     * Creates a new addon sorter.
45
+     * 
46
+     * @param model
47
+     * @param sortByDate
48
+     * @param sortByName
49
+     * @param sortByRating
50
+     * @param sortByStatus
51
+     * @param filter 
52
+     */
53
+    public AddonSorter(final DefaultTableModel model, final ButtonModel sortByDate,
54
+            final ButtonModel sortByName, final ButtonModel sortByRating,
55
+            final ButtonModel sortByStatus, final AddonFilter filter) {
56
+        super(model);
57
+        this.sortByDate = sortByDate;
58
+        this.sortByName = sortByName;
59
+        this.sortByRating = sortByRating;
60
+        this.sortByStatus = sortByStatus;
61
+
62
+        setRowFilter(filter);
63
+        setComparator(0, this);
64
+        toggleSortOrder(0);
65
+    }
66
+
67
+    /** {@inheritDoc} */
68
+    @Override
69
+    public int compare(final AddonInfoLabel o1, final AddonInfoLabel o2) {
70
+        final AddonInfo info1 = o1.getAddonInfo();
71
+        final AddonInfo info2 = o2.getAddonInfo();
72
+        System.out.println("compare");
73
+        if (sortByDate.isSelected()) {
74
+            return info1.getId() - info2.getId();
75
+        } else if (sortByName.isSelected()) {
76
+            return info1.getTitle().compareTo(info2.getTitle());
77
+        } else if (sortByRating.isSelected()) {
78
+            return info1.getRating() - info2.getRating();
79
+        } else if (sortByStatus.isSelected()) {
80
+            return (info1.isVerified() ? 1 : 0) - (info2.isVerified() ? 1 : 0);
81
+        } else {
82
+            return 0;
83
+        }
84
+    }
85
+}

+ 28
- 2
src/com/dmdirc/addons/ui_swing/components/addonbrowser/AddonTable.java 查看文件

@@ -24,6 +24,7 @@
24 24
 package com.dmdirc.addons.ui_swing.components.addonbrowser;
25 25
 
26 26
 import javax.swing.JTable;
27
+import javax.swing.RowSorter;
27 28
 import javax.swing.table.DefaultTableModel;
28 29
 import javax.swing.table.TableCellRenderer;
29 30
 import javax.swing.table.TableModel;
@@ -44,13 +45,13 @@ public class AddonTable extends JTable {
44 45
      * Creates a new addon table.
45 46
      */
46 47
     public AddonTable() {
47
-        super(new DefaultTableModel(new String[]{"Addon",}, 0));
48
+        super(new DefaultTableModel(0, 1));
48 49
         setTableHeader(null);
49 50
     }
50 51
 
51 52
     /** {@inheritDoc} */
52 53
     @Override
53
-    public TableCellRenderer getCellRenderer(int row, int column) {
54
+    public TableCellRenderer getCellRenderer(final int row, final int column) {
54 55
         return new AddonInfoCellRenderer();
55 56
     }
56 57
 
@@ -60,4 +61,29 @@ public class AddonTable extends JTable {
60 61
         return (DefaultTableModel) super.getModel();
61 62
     }
62 63
 
64
+    /** {@inheritDoc} */
65
+    @Override
66
+    public void setModel(final TableModel dataModel) {
67
+        if (!(dataModel instanceof DefaultTableModel)) {
68
+            throw new IllegalArgumentException("Row sorter must be of type DefaultTableModel");
69
+        }
70
+        super.setModel(dataModel);
71
+    }
72
+
73
+    /** {@inheritDoc} */
74
+    @Override
75
+    @SuppressWarnings("unchecked")
76
+    public AddonSorter getRowSorter() {
77
+        return (AddonSorter) super.getRowSorter();
78
+    }
79
+
80
+    /** {@inheritDoc} */
81
+    @Override
82
+    public void setRowSorter(final RowSorter<? extends TableModel> sorter) {
83
+        if (!(sorter instanceof AddonSorter)) {
84
+            throw new IllegalArgumentException("Row sorter must be of type AddonSorter");
85
+        }
86
+        super.setRowSorter(sorter);
87
+    }
88
+
63 89
 }

+ 41
- 96
src/com/dmdirc/addons/ui_swing/components/addonbrowser/BrowserWindow.java 查看文件

@@ -19,12 +19,11 @@
19 19
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 20
  * SOFTWARE.
21 21
  */
22
+
22 23
 package com.dmdirc.addons.ui_swing.components.addonbrowser;
23 24
 
24 25
 import com.dmdirc.Main;
25 26
 import com.dmdirc.addons.ui_swing.MainFrame;
26
-import com.dmdirc.addons.ui_swing.UIUtilities;
27
-import com.dmdirc.addons.ui_swing.components.LoggingSwingWorker;
28 27
 import com.dmdirc.util.ConfigFile;
29 28
 import com.dmdirc.util.InvalidConfigFileException;
30 29
 
@@ -32,25 +31,18 @@ import java.awt.event.ActionEvent;
32 31
 import java.awt.event.ActionListener;
33 32
 import java.io.File;
34 33
 import java.io.IOException;
35
-import java.util.ArrayList;
36
-import java.util.Collections;
37
-import java.util.Comparator;
38
-import java.util.List;
39 34
 import java.util.Map;
40 35
 
41 36
 import javax.swing.BorderFactory;
42 37
 import javax.swing.ButtonGroup;
43
-import javax.swing.DefaultListModel;
44 38
 import javax.swing.JCheckBox;
45 39
 import javax.swing.JDialog;
46
-import javax.swing.JLabel;
47 40
 import javax.swing.JPanel;
48 41
 import javax.swing.JRadioButton;
49 42
 import javax.swing.JScrollPane;
50
-import javax.swing.JTable;
51 43
 import javax.swing.JTextField;
52 44
 
53
-import javax.swing.table.DefaultTableModel;
45
+import javax.swing.SwingUtilities;
54 46
 import net.miginfocom.swing.MigLayout;
55 47
 
56 48
 /**
@@ -58,8 +50,7 @@ import net.miginfocom.swing.MigLayout;
58 50
  * 
59 51
  * @author chris
60 52
  */
61
-public class BrowserWindow extends JDialog implements ActionListener,
62
-        Comparator<AddonInfo> {
53
+public class BrowserWindow extends JDialog implements ActionListener {
63 54
 
64 55
     /**
65 56
      * A version number for this class. It should be changed whenever the class
@@ -82,12 +73,14 @@ public class BrowserWindow extends JDialog implements ActionListener,
82 73
     /** The installed checkbox. */
83 74
     private final JCheckBox installedBox = new JCheckBox("Installed", true);
84 75
     /** The not installed checkbox. */
85
-    private final JCheckBox notinstalledBox = new JCheckBox("Not installed", true);
76
+    private final JCheckBox notinstalledBox = new JCheckBox("Not installed",
77
+            true);
86 78
     /** The panel used to list addons. */
87 79
     private final AddonTable list = new AddonTable();
88 80
     /** The scrollpane for the list panel. */
89 81
     private final JScrollPane scrollPane = new JScrollPane(list,
90
-            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
82
+            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
83
+            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
91 84
     /** The sort by name button. */
92 85
     private final JRadioButton nameButton = new JRadioButton("Name", true);
93 86
     /** The sort by rating button. */
@@ -96,15 +89,19 @@ public class BrowserWindow extends JDialog implements ActionListener,
96 89
     private final JRadioButton dateButton = new JRadioButton("Date", false);
97 90
     /** The sort by status button. */
98 91
     private final JRadioButton statusButton = new JRadioButton("Status", false);
99
-    /** All known addon infos. */
100
-    private final List<AddonInfo> infos = new ArrayList<AddonInfo>();
92
+    /** Row sorter. */
93
+    private final AddonSorter sorter;
94
+    /** Addon filter. */
95
+    private final AddonFilter filter;
101 96
 
102 97
     /**
103 98
      * Creates and displays a new browser window.
104 99
      */
105 100
     public BrowserWindow() {
106
-        super((MainFrame) Main.getUI().getMainWindow(), "DMDirc Addon Browser", false);
107
-        setIconImage(((MainFrame) Main.getUI().getMainWindow()).getIcon().getImage());
101
+        super((MainFrame) Main.getUI().getMainWindow(), "DMDirc Addon Browser",
102
+                false);
103
+        setIconImage(((MainFrame) Main.getUI().getMainWindow()).getIcon().
104
+                getImage());
108 105
         setResizable(false);
109 106
         setLayout(new MigLayout("fill, wmin 650, hmin 600"));
110 107
         scrollPane.getVerticalScrollBar().setUnitIncrement(15);
@@ -144,6 +141,16 @@ public class BrowserWindow extends JDialog implements ActionListener,
144 141
 
145 142
         initListeners();
146 143
 
144
+        filter = new AddonFilter(verifiedBox.getModel(),
145
+                unverifiedBox.getModel(), installedBox.getModel(),
146
+                notinstalledBox.getModel(), pluginsBox.getModel(), themesBox.
147
+                getModel(), actionsBox.getModel(),
148
+                searchBox);
149
+        sorter = new AddonSorter(list.getModel(), dateButton.getModel(), 
150
+                nameButton.getModel(), ratingButton.getModel(),
151
+                statusButton.getModel(), filter);
152
+        list.setRowSorter(sorter);
153
+
147 154
         try {
148 155
             loadData();
149 156
         } catch (IOException ex) {
@@ -170,17 +177,17 @@ public class BrowserWindow extends JDialog implements ActionListener,
170 177
         themesBox.addActionListener(this);
171 178
         actionsBox.addActionListener(this);
172 179
 
173
-        nameButton.addActionListener(this);
174
-        ratingButton.addActionListener(this);
175
-        dateButton.addActionListener(this);
176
-        statusButton.addActionListener(this);
177
-
178 180
         verifiedBox.addActionListener(this);
179 181
         unverifiedBox.addActionListener(this);
180 182
         installedBox.addActionListener(this);
181 183
         notinstalledBox.addActionListener(this);
182 184
 
183 185
         searchBox.addActionListener(this);
186
+
187
+        nameButton.addActionListener(this);
188
+        ratingButton.addActionListener(this);
189
+        dateButton.addActionListener(this);
190
+        statusButton.addActionListener(this);
184 191
     }
185 192
 
186 193
     /**
@@ -190,92 +197,30 @@ public class BrowserWindow extends JDialog implements ActionListener,
190 197
      * @throws InvalidConfigFileException If the file is corrupt somehow
191 198
      */
192 199
     private void loadData() throws IOException, InvalidConfigFileException {
193
-        ConfigFile data = new ConfigFile(Main.getConfigDir() + File.separator + "addons.feed");
200
+        ConfigFile data = new ConfigFile(Main.getConfigDir() + File.separator +
201
+                "addons.feed");
194 202
         data.read();
195
-        int i = 0;
196 203
 
197 204
         for (Map<String, String> entry : data.getKeyDomains().values()) {
198 205
             final AddonInfo info = new AddonInfo(entry);
199
-            infos.add(info);
206
+            list.getModel().addRow(new Object[]{new AddonInfoLabel(info),});
200 207
         }
201
-
202
-        sortAndFilter();
203 208
     }
204 209
 
205 210
     /**
206
-     * Sorts and filters the list of addons according to the currently selected
207
-     * options.
208
-     */
209
-    private void sortAndFilter() {
210
-        list.getModel().setRowCount(0);
211
-        list.add(new JLabel("Sorting list.", JLabel.CENTER), "grow, pushy");
212
-
213
-        new LoggingSwingWorker() {
214
-
215
-            final List<AddonInfo> newInfos = new ArrayList<AddonInfo>();
216
-
217
-            /* {@inheritDoc} */
218
-            @Override
219
-            protected Object doInBackground() {
220
-                for (AddonInfo info : infos) {
221
-                    if ((!verifiedBox.isSelected() && info.isVerified()) ||
222
-                            (!unverifiedBox.isSelected() && !info.isVerified()) ||
223
-                            (!installedBox.isSelected() && info.isInstalled()) ||
224
-                            (!notinstalledBox.isSelected() &&
225
-                            !info.isInstalled()) || (!pluginsBox.isSelected() &&
226
-                            info.getType() == AddonType.TYPE_PLUGIN) ||
227
-                            (!themesBox.isSelected() && info.getType() ==
228
-                            AddonType.TYPE_THEME) ||
229
-                            (!actionsBox.isSelected() && info.getType() ==
230
-                            AddonType.TYPE_ACTION_PACK) || (!searchBox.getText().
231
-                            isEmpty() && !info.matches(searchBox.getText()))) {
232
-                        continue;
233
-                    }
234
-
235
-                    newInfos.add(info);
236
-                }
237
-
238
-                Collections.sort(newInfos, BrowserWindow.this);
239
-                return newInfos;
240
-            }
241
-
242
-            /* {@inheritDoc} */
243
-            @Override
244
-            protected void done() {
245
-                super.done();
246
-
247
-                list.getModel().setRowCount(0);
248
-                for (AddonInfo info : newInfos) {
249
-                    list.getModel().addRow(new Object[] {new AddonInfoLabel(info), });
250
-                }
251
-                UIUtilities.resetScrollPane(scrollPane);
252
-            }
253
-        }.execute();
254
-    }
255
-
256
-    /** 
257 211
      * {@inheritDoc}
258
-     * 
212
+     *
259 213
      * @param e Action event
260 214
      */
261 215
     @Override
262 216
     public void actionPerformed(final ActionEvent e) {
263
-        sortAndFilter();
264
-    }
217
+        SwingUtilities.invokeLater(new Runnable() {
265 218
 
266
-    /** {@inheritDoc} */
267
-    @Override
268
-    public int compare(final AddonInfo o1, final AddonInfo o2) {
269
-        if (dateButton.isSelected()) {
270
-            return o1.getId() - o2.getId();
271
-        } else if (nameButton.isSelected()) {
272
-            return o1.getTitle().compareTo(o2.getTitle());
273
-        } else if (ratingButton.isSelected()) {
274
-            return o1.getRating() - o2.getRating();
275
-        } else if (statusButton.isSelected()) {
276
-            return (o1.isVerified() ? 1 : 0) - (o2.isVerified() ? 1 : 0);
277
-        } else {
278
-            return 0;
279
-        }
219
+            /** {@inheritDoc} */
220
+            @Override
221
+            public void run() {
222
+                sorter.sort();
223
+            }
224
+        });
280 225
     }
281 226
 }

+ 3
- 0
src/com/dmdirc/addons/ui_swing/components/addonbrowser/DownloaderWindow.java 查看文件

@@ -6,6 +6,7 @@
6 6
 package com.dmdirc.addons.ui_swing.components.addonbrowser;
7 7
 
8 8
 import com.dmdirc.Main;
9
+import com.dmdirc.addons.ui_swing.MainFrame;
9 10
 import com.dmdirc.ui.CoreUIUtils;
10 11
 import com.dmdirc.util.DownloadListener;
11 12
 import com.dmdirc.util.Downloader;
@@ -35,6 +36,8 @@ public class DownloaderWindow extends JDialog implements Runnable, DownloadListe
35 36
 
36 37
     /** Instantiates a new downloader window. */
37 38
     public DownloaderWindow() {
39
+        super((MainFrame) Main.getUI().getMainWindow(), "DMDirc Addon Browser",
40
+                false);
38 41
         setTitle("Downloading addon information...");
39 42
         setLayout(new MigLayout("fill"));
40 43
         add(jpb, "grow");

Loading…
取消
儲存