File Source: BrowserWindow.java
/*
P/P * Method: com.dmdirc.addons.addonbrowser.BrowserWindow__static_init
*/
1 /*
2 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22 package com.dmdirc.addons.addonbrowser;
23
24 import com.dmdirc.Main;
25 import com.dmdirc.addons.addonbrowser.AddonInfo.AddonType;
26 import com.dmdirc.addons.ui_swing.MainFrame;
27 import com.dmdirc.addons.ui_swing.SwingController;
28 import com.dmdirc.addons.ui_swing.components.LoggingSwingWorker;
29 import com.dmdirc.util.ConfigFile;
30 import com.dmdirc.util.InvalidConfigFileException;
31
32 import java.awt.event.ActionEvent;
33 import java.awt.event.ActionListener;
34 import java.io.File;
35 import java.io.IOException;
36 import java.util.ArrayList;
37 import java.util.Collections;
38 import java.util.Comparator;
39 import java.util.List;
40 import java.util.Map;
41
42 import javax.swing.BorderFactory;
43 import javax.swing.ButtonGroup;
44 import javax.swing.DefaultListModel;
45 import javax.swing.JCheckBox;
46 import javax.swing.JDialog;
47 import javax.swing.JLabel;
48 import javax.swing.JList;
49 import javax.swing.JPanel;
50 import javax.swing.JRadioButton;
51 import javax.swing.JScrollPane;
52 import javax.swing.JTextField;
53 import javax.swing.SwingUtilities;
54
55 import net.miginfocom.swing.MigLayout;
56
57 /**
58 * The main window that allows users to browse addons.
59 *
60 * @author chris
61 */
/*
P/P * Method: JScrollPane access$1000(BrowserWindow)
*
* Preconditions:
* x0 != null
*
* Postconditions:
* return_value == x0.scrollPane
* init'ed(return_value)
*/
62 public class BrowserWindow extends JDialog implements ActionListener,
63 Comparator<AddonInfo> {
64
65 /**
66 * A version number for this class. It should be changed whenever the class
67 * structure is changed (or anything else that would prevent serialized
68 * objects being unserialized with the new class).
69 */
70 private static final long serialVersionUID = 1;
71 /** The search box. */
72 private final JTextField searchBox = new JTextField();
73 /** The plugins check box. */
74 private final JCheckBox pluginsBox = new JCheckBox("Plugins", true);
75 /** The themes check box. */
76 private final JCheckBox themesBox = new JCheckBox("Themes", true);
77 /** The actions check box. */
78 private final JCheckBox actionsBox = new JCheckBox("Action Packs", true);
79 /** The verified check box. */
80 private final JCheckBox verifiedBox = new JCheckBox("Verified", true);
81 /** The unverified check box. */
82 private final JCheckBox unverifiedBox = new JCheckBox("Unverified", false);
83 /** The installed checkbox. */
84 private final JCheckBox installedBox = new JCheckBox("Installed", true);
85 /** The not installed checkbox. */
86 private final JCheckBox notinstalledBox = new JCheckBox("Not installed", true);
87 /** The panel used to list addons. */
88 private final JList list = new JList(new DefaultListModel());
89 /** The scrollpane for the list panel. */
90 private final JScrollPane scrollPane = new JScrollPane(list,
91 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
92 /** The sort by name button. */
93 private final JRadioButton nameButton = new JRadioButton("Name", true);
94 /** The sort by rating button. */
95 private final JRadioButton ratingButton = new JRadioButton("Rating", false);
96 /** The sort by date button. */
97 private final JRadioButton dateButton = new JRadioButton("Date", false);
98 /** The sort by status button. */
99 private final JRadioButton statusButton = new JRadioButton("Status", false);
100 /** All known addon infos. */
101 private final List<AddonInfo> infos = new ArrayList<AddonInfo>();
102
103 /**
104 * Creates and displays a new browser window.
105 */
106 public BrowserWindow() {
/*
P/P * Method: void com.dmdirc.addons.addonbrowser.BrowserWindow()
*
* Preconditions:
* com/dmdirc/Main.controller != null
* (soft) init'ed(com/dmdirc/Main.configdir)
*
* Presumptions:
* com.dmdirc.addons.ui_swing.MainFrame:getIcon(...)@108 != null
* com.dmdirc.ui.interfaces.UIController:getMainWindow(...)@108 != null
* javax.swing.JScrollPane:getVerticalScrollBar(...)@111 != null
*
* Postconditions:
* com/dmdirc/Main.configdir == One-of{old com/dmdirc/Main.configdir, &java.lang.StringBuilder:toString(...)}
* init'ed(com/dmdirc/Main.configdir)
* java.lang.StringBuilder:toString(...)._tainted == 0
* this.actionsBox == &new JCheckBox(BrowserWindow#4)
* this.dateButton == &new JRadioButton(BrowserWindow#14)
* this.infos == &new ArrayList(BrowserWindow#16)
* this.installedBox == &new JCheckBox(BrowserWindow#7)
* this.list == &new JList(BrowserWindow#9)
* this.nameButton == &new JRadioButton(BrowserWindow#12)
* this.notinstalledBox == &new JCheckBox(BrowserWindow#8)
* ...
*/
107 super((MainFrame) Main.getUI().getMainWindow(), "DMDirc Addon Browser", false);
108 setIconImage(((MainFrame) Main.getUI().getMainWindow()).getIcon().getImage());
109 setResizable(false);
110 setLayout(new MigLayout("fill, wmin 650, hmin 600"));
111 scrollPane.getVerticalScrollBar().setUnitIncrement(15);
112 list.setCellRenderer(new AddonInfoListCellRenderer());
113
114 JPanel panel = new JPanel(new MigLayout("fill"));
115 panel.setBorder(BorderFactory.createTitledBorder("Search"));
116 panel.add(searchBox, "growx");
117 add(panel, "width 150!");
118
119 panel = new JPanel(new MigLayout("fill"));
120 panel.setBorder(BorderFactory.createTitledBorder("Results"));
121 panel.add(scrollPane, "grow");
122 add(panel, "wrap, spany 4, grow");
123
124 panel = new JPanel(new MigLayout("fill, wrap"));
125 panel.setBorder(BorderFactory.createTitledBorder("Types"));
126 panel.add(pluginsBox, "grow");
127 panel.add(themesBox, "grow");
128 panel.add(actionsBox, "grow");
129 add(panel, "wrap, pushy, growy, width 150!");
130
131 panel = new JPanel(new MigLayout("fill, wrap"));
132 panel.setBorder(BorderFactory.createTitledBorder("Status"));
133 panel.add(verifiedBox, "grow");
134 panel.add(unverifiedBox, "grow");
135 panel.add(installedBox, "grow");
136 panel.add(notinstalledBox, "grow");
137 add(panel, "wrap, pushy, growy, width 150!");
138
139 panel = new JPanel(new MigLayout("fill, wrap"));
140 panel.setBorder(BorderFactory.createTitledBorder("Sort by"));
141 panel.add(nameButton, "grow");
142 panel.add(ratingButton, "grow");
143 panel.add(dateButton, "grow");
144 panel.add(statusButton, "grow");
145 add(panel, "wrap, pushy, growy, width 150!");
146
147 initListeners();
148
149 try {
150 loadData();
151 } catch (IOException ex) {
152 } catch (InvalidConfigFileException ex) {
153 }
154
155 pack();
156 setLocationRelativeTo((MainFrame) Main.getUI().getMainWindow());
157 setVisible(true);
158 setLocationRelativeTo((MainFrame) Main.getUI().getMainWindow());
159 }
160
161 /**
162 * Registers listeners and sets up button groups.
163 */
164 private void initListeners() {
/*
P/P * Method: void initListeners()
*
* Preconditions:
* this.actionsBox != null
* this.dateButton != null
* this.installedBox != null
* this.nameButton != null
* this.notinstalledBox != null
* this.pluginsBox != null
* this.ratingButton != null
* this.searchBox != null
* this.statusButton != null
* this.themesBox != null
* ...
*/
165 final ButtonGroup group = new ButtonGroup();
166 group.add(nameButton);
167 group.add(ratingButton);
168 group.add(dateButton);
169 group.add(statusButton);
170
171 pluginsBox.addActionListener(this);
172 themesBox.addActionListener(this);
173 actionsBox.addActionListener(this);
174
175 nameButton.addActionListener(this);
176 ratingButton.addActionListener(this);
177 dateButton.addActionListener(this);
178 statusButton.addActionListener(this);
179
180 verifiedBox.addActionListener(this);
181 unverifiedBox.addActionListener(this);
182 installedBox.addActionListener(this);
183 notinstalledBox.addActionListener(this);
184
185 searchBox.addActionListener(this);
186 }
187
188 /**
189 * Loads addon data from the locally cached feed file.
190 *
191 * @throws IOException If the file can't be read
192 * @throws InvalidConfigFileException If the file is corrupt somehow
193 */
194 private void loadData() throws IOException, InvalidConfigFileException {
/*
P/P * Method: void loadData()
*
* Preconditions:
* init'ed(com/dmdirc/Main.configdir)
* this.list != null
* (soft) this.infos != null
*
* Presumptions:
* com.dmdirc.util.ConfigFile:getKeyDomains(...)@199 != null
* init'ed(java.io.File.separator)
* java.util.Iterator:next(...)@199 != null
* java.util.Map:values(...)@199 != null
*
* Postconditions:
* com/dmdirc/Main.configdir == One-of{old com/dmdirc/Main.configdir, &java.lang.StringBuilder:toString(...)}
* com/dmdirc/Main.configdir != null
* java.lang.StringBuilder:toString(...)._tainted == 0
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@199: {0}, {1}
*/
195 ConfigFile data = new ConfigFile(Main.getConfigDir() + File.separator + "addons.feed");
196 data.read();
197 int i = 0;
198
199 for (Map<String, String> entry : data.getKeyDomains().values()) {
200 final AddonInfo info = new AddonInfo(entry);
201 infos.add(info);
202 }
203
204 sortAndFilter();
205 }
206
207 /**
208 * Sorts and filters the list of addons according to the currently selected
209 * options.
210 */
211 private void sortAndFilter() {
/*
P/P * Method: void sortAndFilter()
*
* Preconditions:
* this.list != null
*
* Presumptions:
* javax.swing.JList:getModel(...)@212 != null
*/
212 ((DefaultListModel) list.getModel()).clear();
213 list.add(new JLabel("Sorting list.", JLabel.CENTER), "grow, pushy");
214
/*
P/P * Method: void com.dmdirc.addons.addonbrowser.BrowserWindow$1(BrowserWindow)
*
* Postconditions:
* this.newInfos == &new ArrayList(BrowserWindow$1#1)
* new ArrayList(BrowserWindow$1#1) num objects == 1
*/
215 new LoggingSwingWorker() {
216
217 final List<AddonInfo> newInfos = new ArrayList<AddonInfo>();
218
219 /* {@inheritDoc} */
220 @Override
221 protected Object doInBackground() {
/*
P/P * Method: Object doInBackground()
*
* Preconditions:
* this.infos != null
* (soft) this.newInfos != null
* (soft) this.actionsBox != null
* (soft) this.installedBox != null
* (soft) this.notinstalledBox != null
* (soft) this.pluginsBox != null
* (soft) this.searchBox != null
* (soft) this.themesBox != null
* (soft) this.unverifiedBox != null
* (soft) this.verifiedBox != null
*
* Presumptions:
* info.description@222 != null
* info.title@222 != null
* java.util.Iterator:next(...)@222 != null
* javax.swing.JTextField:getText(...)@223 != null
*
* Postconditions:
* return_value == this.newInfos
* return_value != null
*
* Test Vectors:
* info.type@222: Addr_Set{&com.dmdirc.addons.addonbrowser.AddonInfo$AddonType__static_init.new AddonInfo$AddonType(AddonInfo$AddonType__static_init#1)}, Addr_Set{&com.dmdirc.addons.addonbrowser.AddonInfo$AddonType__static_init.new AddonInfo$AddonType(AddonInfo$AddonType__static_init#2)}, Addr_Set{&com.dmdirc.addons.addonbrowser.AddonInfo$AddonType__static_init.new AddonInfo$AddonType(AddonInfo$AddonType__static_init#3)}
* info.verified@222: {1}, {0}
* java.lang.String:isEmpty(...)@223: {1}, {0}
* java.util.Iterator:hasNext(...)@222: {0}, {1}
* javax.swing.JCheckBox:isSelected(...)@223: {1}, {0}
*/
222 for (AddonInfo info : infos) {
223 if ((!verifiedBox.isSelected() && info.isVerified()) ||
224 (!unverifiedBox.isSelected() && !info.isVerified()) ||
225 (!installedBox.isSelected() && info.isInstalled()) ||
226 (!notinstalledBox.isSelected() &&
227 !info.isInstalled()) || (!pluginsBox.isSelected() &&
228 info.getType() == AddonType.TYPE_PLUGIN) ||
229 (!themesBox.isSelected() && info.getType() ==
230 AddonType.TYPE_THEME) ||
231 (!actionsBox.isSelected() && info.getType() ==
232 AddonType.TYPE_ACTION_PACK) || (!searchBox.getText().
233 isEmpty() && !info.matches(searchBox.getText()))) {
234 continue;
235 }
236
237 newInfos.add(info);
238 }
239
240 Collections.sort(newInfos, BrowserWindow.this);
241 return newInfos;
242 }
243
244 /* {@inheritDoc} */
245 @Override
246 protected void done() {
/*
P/P * Method: void done()
*
* Preconditions:
* this.newInfos != null
* this.list != null
*
* Presumptions:
* javax.swing.JList:getModel(...)@249 != null
* javax.swing.JList:getModel(...)@251 != null
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@250: {0}, {1}
*/
247 super.done();
248
249 ((DefaultListModel) list.getModel()).clear();
250 for (AddonInfo info : newInfos) {
251 ((DefaultListModel) list.getModel()).addElement(info);
252 }
/*
P/P * Method: void com.dmdirc.addons.addonbrowser.BrowserWindow$1$1(BrowserWindow$1)
*/
253 SwingUtilities.invokeLater(new Runnable() {
254
255 @Override
256 public void run() {
/*
P/P * Method: void run()
*
* Preconditions:
* this.scrollPane != null
*
* Presumptions:
* javax.swing.JScrollPane:getVerticalScrollBar(...)@257 != null
*/
257 scrollPane.getVerticalScrollBar().setValue(0);
258 }
259 });
260 }
261 }.execute();
262 }
263
264 /**
265 * {@inheritDoc}
266 *
267 * @param e Action event
268 */
269 @Override
270 public void actionPerformed(final ActionEvent e) {
/*
P/P * Method: void actionPerformed(ActionEvent)
*
* Preconditions:
* this.list != null
*/
271 sortAndFilter();
272 }
273
274 /** {@inheritDoc} */
275 @Override
276 public int compare(final AddonInfo o1, final AddonInfo o2) {
/*
P/P * Method: int compare(AddonInfo, AddonInfo)
*
* Preconditions:
* this.dateButton != null
* (soft) o1 != null
* (soft) o1.title != null
* (soft) o2 != null
* (soft) o2.id - o1.id in {-232+1..231}
* (soft) o2.rating - o1.rating in {-232+1..231}
* (soft) this.nameButton != null
* (soft) this.ratingButton != null
* (soft) this.statusButton != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* javax.swing.JRadioButton:isSelected(...)@277: {0}, {1}
* javax.swing.JRadioButton:isSelected(...)@279: {0}, {1}
* javax.swing.JRadioButton:isSelected(...)@281: {0}, {1}
* javax.swing.JRadioButton:isSelected(...)@283: {0}, {1}
*/
277 if (dateButton.isSelected()) {
278 return o1.getId() - o2.getId();
279 } else if (nameButton.isSelected()) {
280 return o1.getTitle().compareTo(o2.getTitle());
281 } else if (ratingButton.isSelected()) {
282 return o1.getRating() - o2.getRating();
283 } else if (statusButton.isSelected()) {
284 return (o1.isVerified() ? 1 : 0) - (o2.isVerified() ? 1 : 0);
285 } else {
286 return 0;
287 }
288 }
289 }
SofCheck Inspector Build Version : 2.17854
| BrowserWindow.java |
2009-Jun-25 01:54:24 |
| BrowserWindow.class |
2009-Sep-02 17:04:17 |
| BrowserWindow$1.class |
2009-Sep-02 17:04:17 |
| BrowserWindow$1$1.class |
2009-Sep-02 17:04:17 |