GUI search: regorg done
[fanfix.git] / src / be / nikiroo / fanfix / reader / ui / GuiReaderSearchFrame.java
CommitLineData
4357eb54
NR
1package be.nikiroo.fanfix.reader.ui;
2
3import java.awt.BorderLayout;
d16065ec 4import java.awt.Component;
4357eb54
NR
5import java.awt.EventQueue;
6import java.awt.event.ActionEvent;
7import java.awt.event.ActionListener;
4357eb54
NR
8import java.lang.reflect.InvocationTargetException;
9import java.util.ArrayList;
10import java.util.List;
11
4357eb54
NR
12import javax.swing.JComboBox;
13import javax.swing.JFrame;
08e2185a 14import javax.swing.JLabel;
4357eb54
NR
15import javax.swing.JPanel;
16import javax.swing.JScrollPane;
4357eb54
NR
17
18import be.nikiroo.fanfix.Instance;
19import be.nikiroo.fanfix.data.MetaData;
d16065ec 20import be.nikiroo.fanfix.reader.ui.GuiReaderBook.BookActionListener;
4357eb54
NR
21import be.nikiroo.fanfix.searchable.BasicSearchable;
22import be.nikiroo.fanfix.searchable.SearchableTag;
23import be.nikiroo.fanfix.supported.SupportType;
24
25/**
26 * This frame will allow you to search through the supported websites for new
27 * stories/comics.
28 *
29 * @author niki
30 */
6e950847
NR
31// JCombobox<E> not 1.6 compatible
32@SuppressWarnings({ "unchecked", "rawtypes" })
741e8467 33public class GuiReaderSearchFrame extends JFrame {
4357eb54
NR
34 private static final long serialVersionUID = 1L;
35
36 private List<SupportType> supportTypes;
37 private SupportType supportType;
4357eb54
NR
38 private int page;
39 private int maxPage;
40
415c7454 41 private JComboBox comboSupportTypes;
9c598207 42 private GuiReaderSearchByPanel searchPanel;
4357eb54
NR
43
44 private boolean seeWordcount;
45 private GuiReaderGroup books;
46
741e8467 47 public GuiReaderSearchFrame(final GuiReader reader) {
4357eb54
NR
48 super("Browse stories");
49 setLayout(new BorderLayout());
50 setSize(800, 600);
51
7cc1e743 52 page = 1;
4357eb54
NR
53 maxPage = -1;
54
55 supportTypes = new ArrayList<SupportType>();
56 for (SupportType type : SupportType.values()) {
57 if (BasicSearchable.getSearchable(type) != null) {
58 supportTypes.add(type);
59 }
60 }
61 supportType = supportTypes.isEmpty() ? null : supportTypes.get(0);
62
415c7454 63 comboSupportTypes = new JComboBox(
4357eb54
NR
64 supportTypes.toArray(new SupportType[] {}));
65 comboSupportTypes.addActionListener(new ActionListener() {
66 @Override
67 public void actionPerformed(ActionEvent e) {
9c598207 68 setWaiting(true);
7cc1e743
NR
69 updateSupportType(
70 (SupportType) comboSupportTypes.getSelectedItem(),
71 new Runnable() {
72 @Override
73 public void run() {
9c598207 74 setWaiting(false);
7cc1e743
NR
75 }
76 });
4357eb54
NR
77 }
78 });
08e2185a
NR
79 JPanel searchSites = new JPanel(new BorderLayout());
80 searchSites.add(comboSupportTypes, BorderLayout.CENTER);
81 searchSites.add(new JLabel(" " + "Website : "), BorderLayout.WEST);
4357eb54 82
9c598207
NR
83 searchPanel = new GuiReaderSearchByPanel(supportType,
84 new GuiReaderSearchByPanel.Waitable() {
7cc1e743 85 @Override
9c598207
NR
86 public void setWaiting(boolean waiting) {
87 GuiReaderSearchFrame.this.setWaiting(waiting);
7cc1e743
NR
88 }
89 });
90
ce5a42e7
N
91 searchPanel.addActionListener(new ActionListener() {
92 @Override
93 public void actionPerformed(ActionEvent e) {
9c598207 94 updatePages(searchPanel.getPage(), searchPanel.getMaxPage());
ce5a42e7
N
95 List<GuiReaderBookInfo> infos = new ArrayList<GuiReaderBookInfo>();
96 for (MetaData meta : searchPanel.getStories()) {
97 infos.add(GuiReaderBookInfo.fromMeta(meta));
98 }
99
100 updateBooks(infos);
101
102 // ! 1-based index !
103 int item = searchPanel.getStoryItem();
104 if (item > 0 && item <= books.getBooksCount()) {
105 // TODO: "click" on item ITEM
106 }
107 }
108 });
4357eb54 109
08e2185a
NR
110 JPanel top = new JPanel(new BorderLayout());
111 top.add(searchSites, BorderLayout.NORTH);
ce5a42e7 112 top.add(searchPanel, BorderLayout.CENTER);
4357eb54
NR
113
114 add(top, BorderLayout.NORTH);
115
116 books = new GuiReaderGroup(reader, null, null);
d16065ec
NR
117 books.setActionListener(new BookActionListener() {
118 @Override
119 public void select(GuiReaderBook book) {
120 }
121
122 @Override
123 public void popupRequested(GuiReaderBook book, Component target,
124 int x, int y) {
125 }
126
127 @Override
128 public void action(GuiReaderBook book) {
129 new GuiReaderSearchAction(reader.getLibrary(), book.getInfo())
130 .setVisible(true);
131 }
132 });
4357eb54
NR
133 JScrollPane scroll = new JScrollPane(books);
134 scroll.getVerticalScrollBar().setUnitIncrement(16);
135 add(scroll, BorderLayout.CENTER);
4357eb54
NR
136 }
137
9c598207
NR
138 private void updateSupportType(final SupportType supportType,
139 final Runnable inUi) {
140 this.supportType = supportType;
141 comboSupportTypes.setSelectedItem(supportType);
142 books.clear();
81acd363 143
9c598207 144 new Thread(new Runnable() {
81acd363
NR
145 @Override
146 public void run() {
9c598207
NR
147 searchPanel.setSupportType(supportType);
148 inUi(inUi);
7cc1e743 149 }
9c598207 150 }).start();
7cc1e743
NR
151 }
152
9c598207 153 private void updatePages(final int page, final int maxPage) {
7cc1e743
NR
154 inUi(new Runnable() {
155 @Override
156 public void run() {
9c598207 157 GuiReaderSearchFrame.this.page = page;
7cc1e743
NR
158 GuiReaderSearchFrame.this.maxPage = maxPage;
159
160 // TODO: gui
9c598207 161 System.out.println("page: " + page);
81acd363
NR
162 System.out.println("max page: " + maxPage);
163 }
164 });
165 }
166
81acd363 167 private void updateBooks(final List<GuiReaderBookInfo> infos) {
9c598207 168 setWaiting(true);
81acd363
NR
169 inUi(new Runnable() {
170 @Override
171 public void run() {
172 books.refreshBooks(infos, seeWordcount);
9c598207 173 setWaiting(false);
81acd363
NR
174 }
175 });
176 }
177
178 // item 0 = no selection, else = default selection
4357eb54
NR
179 public void search(final SupportType searchOn, final String keywords,
180 final int page, final int item) {
9c598207
NR
181 setWaiting(true);
182 new Thread(new Runnable() {
7cc1e743
NR
183 @Override
184 public void run() {
9c598207
NR
185 searchPanel.setSupportType(searchOn);
186 searchPanel.search(keywords, page, item);
187 inUi(new Runnable() {
188 @Override
189 public void run() {
190 setWaiting(false);
191 }
192 });
7cc1e743 193 }
9c598207 194 }).start();
4357eb54
NR
195 }
196
6e950847 197 // tag: null = base tags
c499d79f
NR
198 public void searchTag(final SupportType searchOn, final int page,
199 final int item, final SearchableTag tag) {
9c598207
NR
200 setWaiting(true);
201 new Thread(new Runnable() {
c499d79f
NR
202 @Override
203 public void run() {
9c598207
NR
204 searchPanel.setSupportType(searchOn);
205 searchPanel.searchTag(tag, page, item);
206 inUi(new Runnable() {
7cc1e743
NR
207 @Override
208 public void run() {
9c598207 209 setWaiting(false);
7cc1e743
NR
210 }
211 });
4357eb54 212 }
9c598207 213 }).start();
bf2b37b0
NR
214 }
215
4357eb54
NR
216 /**
217 * Process the given action in the main Swing UI thread.
218 * <p>
219 * The code will make sure the current thread is the main UI thread and, if
220 * not, will switch to it before executing the runnable.
221 * <p>
222 * Synchronous operation.
223 *
224 * @param run
225 * the action to run
226 */
741e8467 227 static void inUi(final Runnable run) {
4357eb54
NR
228 if (EventQueue.isDispatchThread()) {
229 run.run();
230 } else {
231 try {
232 EventQueue.invokeAndWait(run);
233 } catch (InterruptedException e) {
bf2b37b0 234 error(e);
4357eb54 235 } catch (InvocationTargetException e) {
bf2b37b0 236 error(e);
4357eb54
NR
237 }
238 }
239 }
c499d79f 240
741e8467 241 static void error(Exception e) {
bf2b37b0
NR
242 Instance.getTraceHandler().error(e);
243 }
244
741e8467
NR
245 static void error(String e) {
246 Instance.getTraceHandler().error(e);
247 }
7cc1e743 248
9c598207
NR
249 /**
250 * Enables or disables this component, depending on the value of the
251 * parameter <code>b</code>. An enabled component can respond to user input
252 * and generate events. Components are enabled initially by default.
253 * <p>
254 * Disabling this component will also affect its children.
255 *
256 * @param b
257 * If <code>true</code>, this component is enabled; otherwise
258 * this component is disabled
259 */
260 @Override
261 public void setEnabled(boolean b) {
262 super.setEnabled(b);
263 books.setEnabled(b);
264 searchPanel.setEnabled(b);
265 }
266
267 private void setWaiting(final boolean waiting) {
c499d79f
NR
268 inUi(new Runnable() {
269 @Override
270 public void run() {
741e8467 271 GuiReaderSearchFrame.this.setEnabled(!waiting);
c499d79f
NR
272 }
273 });
274 }
4357eb54 275}