Commit | Line | Data |
---|---|---|
a6395bef NR |
1 | package be.nikiroo.fanfix.reader; |
2 | ||
d3c84ac3 | 3 | import java.awt.BorderLayout; |
b4dc6ab5 | 4 | import java.awt.Color; |
a6395bef | 5 | import java.awt.Desktop; |
a6395bef NR |
6 | import java.awt.event.ActionEvent; |
7 | import java.awt.event.ActionListener; | |
333f0e7b NR |
8 | import java.awt.event.KeyEvent; |
9 | import java.awt.event.WindowEvent; | |
10 | import java.io.File; | |
a6395bef | 11 | import java.io.IOException; |
333f0e7b | 12 | import java.util.ArrayList; |
a6395bef NR |
13 | import java.util.List; |
14 | ||
a6395bef | 15 | import javax.swing.JFrame; |
333f0e7b NR |
16 | import javax.swing.JMenu; |
17 | import javax.swing.JMenuBar; | |
18 | import javax.swing.JMenuItem; | |
19 | import javax.swing.JOptionPane; | |
20 | import javax.swing.JPanel; | |
d3c84ac3 | 21 | import javax.swing.JScrollPane; |
3b2b638f | 22 | import javax.swing.SwingUtilities; |
a6395bef NR |
23 | |
24 | import be.nikiroo.fanfix.Instance; | |
b4dc6ab5 | 25 | import be.nikiroo.fanfix.bundles.UiConfig; |
a6395bef | 26 | import be.nikiroo.fanfix.data.MetaData; |
92fb0719 | 27 | import be.nikiroo.fanfix.reader.LocalReaderBook.BookActionListener; |
3b2b638f NR |
28 | import be.nikiroo.utils.Progress; |
29 | import be.nikiroo.utils.ui.ProgressBar; | |
33ab6d12 | 30 | import be.nikiroo.utils.ui.WrapLayout; |
a6395bef NR |
31 | |
32 | class LocalReaderFrame extends JFrame { | |
33 | private static final long serialVersionUID = 1L; | |
34 | private LocalReader reader; | |
333f0e7b NR |
35 | private List<MetaData> stories; |
36 | private List<LocalReaderBook> books; | |
37 | private JPanel bookPane; | |
38 | private String type; | |
b4dc6ab5 | 39 | private Color color; |
3b2b638f NR |
40 | private ProgressBar pgBar; |
41 | private JMenuBar bar; | |
a6395bef | 42 | |
333f0e7b | 43 | public LocalReaderFrame(LocalReader reader, String type) { |
b4dc6ab5 | 44 | super("Fanfix Library"); |
a6395bef NR |
45 | |
46 | this.reader = reader; | |
47 | ||
48 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
49 | setSize(800, 600); | |
d3c84ac3 | 50 | setLayout(new BorderLayout()); |
a6395bef | 51 | |
333f0e7b | 52 | books = new ArrayList<LocalReaderBook>(); |
b4dc6ab5 NR |
53 | bookPane = new JPanel(new WrapLayout(WrapLayout.LEADING, 5, 5)); |
54 | ||
3b2b638f | 55 | color = Instance.getUiConfig().getColor(UiConfig.BACKGROUND_COLOR); |
b4dc6ab5 NR |
56 | |
57 | if (color != null) { | |
58 | setBackground(color); | |
59 | bookPane.setBackground(color); | |
60 | } | |
d3c84ac3 | 61 | |
b4dc6ab5 NR |
62 | JScrollPane scroll = new JScrollPane(bookPane); |
63 | scroll.getVerticalScrollBar().setUnitIncrement(16); | |
64 | add(scroll, BorderLayout.CENTER); | |
a6395bef | 65 | |
3b2b638f NR |
66 | pgBar = new ProgressBar(); |
67 | add(pgBar, BorderLayout.SOUTH); | |
68 | ||
333f0e7b NR |
69 | refreshBooks(type); |
70 | setJMenuBar(createMenu()); | |
71 | ||
72 | setVisible(true); | |
73 | } | |
74 | ||
75 | private void refreshBooks(String type) { | |
76 | this.type = type; | |
77 | stories = Instance.getLibrary().getList(type); | |
78 | books.clear(); | |
79 | bookPane.removeAll(); | |
80 | for (MetaData meta : stories) { | |
81 | LocalReaderBook book = new LocalReaderBook(meta); | |
b4dc6ab5 NR |
82 | if (color != null) { |
83 | book.setBackground(color); | |
84 | } | |
85 | ||
333f0e7b NR |
86 | books.add(book); |
87 | final String luid = meta.getLuid(); | |
92fb0719 | 88 | book.addActionListener(new BookActionListener() { |
333f0e7b NR |
89 | public void select(LocalReaderBook book) { |
90 | for (LocalReaderBook abook : books) { | |
91 | abook.setSelected(abook == book); | |
92 | } | |
93 | } | |
94 | ||
95 | public void action(LocalReaderBook book) { | |
3b2b638f NR |
96 | final Progress pg = new Progress(); |
97 | outOfUi(pg, new Runnable() { | |
98 | public void run() { | |
99 | try { | |
100 | File target = LocalReaderFrame.this.reader | |
101 | .getTarget(luid, pg); | |
63985d92 NR |
102 | // TODO: allow custom programs, with |
103 | // Desktop/xdg-open fallback | |
104 | try { | |
105 | Desktop.getDesktop().browse(target.toURI()); | |
106 | } catch (UnsupportedOperationException e) { | |
107 | String browsers[] = new String[] { | |
108 | "xdg-open", "epiphany", | |
109 | "konqueror", "firefox", "chrome", | |
110 | "google-chrome", "mozilla" }; | |
111 | ||
112 | Runtime runtime = Runtime.getRuntime(); | |
113 | for (String browser : browsers) { | |
114 | try { | |
115 | runtime.exec(new String[] { | |
116 | browser, | |
117 | target.getAbsolutePath() }); | |
118 | runtime = null; | |
119 | break; | |
120 | } catch (IOException ioe) { | |
121 | // continue, try next browser | |
122 | } | |
123 | } | |
124 | ||
125 | if (runtime != null) { | |
126 | throw new IOException( | |
127 | "Cannot find a working GUI browser..."); | |
128 | } | |
129 | } | |
3b2b638f NR |
130 | } catch (IOException e) { |
131 | Instance.syserr(e); | |
132 | } | |
133 | } | |
134 | }); | |
a6395bef NR |
135 | } |
136 | }); | |
137 | ||
333f0e7b | 138 | bookPane.add(book); |
a6395bef NR |
139 | } |
140 | ||
333f0e7b NR |
141 | bookPane.validate(); |
142 | bookPane.repaint(); | |
143 | } | |
144 | ||
145 | private JMenuBar createMenu() { | |
3b2b638f | 146 | bar = new JMenuBar(); |
333f0e7b NR |
147 | |
148 | JMenu file = new JMenu("File"); | |
149 | ||
150 | JMenuItem imprt = new JMenuItem("Import", KeyEvent.VK_I); | |
151 | imprt.addActionListener(new ActionListener() { | |
152 | public void actionPerformed(ActionEvent e) { | |
3b2b638f NR |
153 | final String url = JOptionPane.showInputDialog( |
154 | LocalReaderFrame.this, "url of the story to import?", | |
b4dc6ab5 NR |
155 | "Importing from URL", JOptionPane.QUESTION_MESSAGE); |
156 | if (url != null && !url.isEmpty()) { | |
3b2b638f NR |
157 | final Progress pg = new Progress("Importing " + url); |
158 | outOfUi(pg, new Runnable() { | |
159 | public void run() { | |
160 | Exception ex = null; | |
161 | try { | |
162 | Instance.getLibrary().imprt( | |
163 | BasicReader.getUrl(url), pg); | |
164 | } catch (IOException e) { | |
165 | ex = e; | |
166 | } | |
167 | ||
168 | final Exception e = ex; | |
169 | ||
170 | final boolean ok = (e == null); | |
171 | SwingUtilities.invokeLater(new Runnable() { | |
172 | public void run() { | |
173 | if (!ok) { | |
174 | JOptionPane.showMessageDialog( | |
175 | LocalReaderFrame.this, | |
176 | "Cannot import: " + url, | |
177 | e.getMessage(), | |
178 | JOptionPane.ERROR_MESSAGE); | |
179 | ||
180 | setAllEnabled(true); | |
181 | } else { | |
182 | refreshBooks(type); | |
183 | } | |
184 | } | |
185 | }); | |
186 | } | |
187 | }); | |
333f0e7b NR |
188 | } |
189 | } | |
190 | }); | |
191 | JMenu types = new JMenu("Type"); | |
192 | List<String> tt = Instance.getLibrary().getTypes(); | |
193 | tt.add(0, null); | |
194 | for (final String type : tt) { | |
195 | JMenuItem item = new JMenuItem(type == null ? "[all]" : type); | |
196 | item.addActionListener(new ActionListener() { | |
197 | public void actionPerformed(ActionEvent e) { | |
198 | refreshBooks(type); | |
199 | } | |
200 | }); | |
201 | types.add(item); | |
202 | } | |
203 | JMenuItem exit = new JMenuItem("Exit", KeyEvent.VK_X); | |
204 | exit.addActionListener(new ActionListener() { | |
205 | public void actionPerformed(ActionEvent e) { | |
206 | LocalReaderFrame.this.dispatchEvent(new WindowEvent( | |
207 | LocalReaderFrame.this, WindowEvent.WINDOW_CLOSING)); | |
208 | } | |
209 | }); | |
210 | ||
211 | file.add(imprt); | |
212 | file.add(types); | |
213 | file.addSeparator(); | |
214 | file.add(exit); | |
215 | ||
216 | bar.add(file); | |
217 | ||
218 | return bar; | |
a6395bef | 219 | } |
3b2b638f NR |
220 | |
221 | private void outOfUi(final Progress pg, final Runnable run) { | |
222 | pgBar.setProgress(pg); | |
223 | ||
224 | SwingUtilities.invokeLater(new Runnable() { | |
225 | public void run() { | |
226 | setAllEnabled(false); | |
227 | pgBar.addActioListener(new ActionListener() { | |
228 | public void actionPerformed(ActionEvent e) { | |
229 | pgBar.setProgress(null); | |
230 | setAllEnabled(true); | |
231 | } | |
232 | }); | |
233 | } | |
234 | }); | |
235 | ||
236 | new Thread(new Runnable() { | |
237 | public void run() { | |
238 | run.run(); | |
239 | if (!pg.isDone()) { | |
240 | pg.setProgress(pg.getMax()); | |
241 | } | |
242 | } | |
243 | }).start(); | |
244 | } | |
245 | ||
246 | public void setAllEnabled(boolean enabled) { | |
247 | for (LocalReaderBook book : books) { | |
248 | book.setEnabled(enabled); | |
249 | book.validate(); | |
250 | book.repaint(); | |
251 | } | |
252 | bar.setEnabled(enabled); | |
253 | bookPane.setEnabled(enabled); | |
254 | bookPane.validate(); | |
255 | bookPane.repaint(); | |
256 | setEnabled(enabled); | |
257 | validate(); | |
258 | repaint(); | |
259 | } | |
a6395bef | 260 | } |