Add progress reporting on GUI
[fanfix.git] / src / be / nikiroo / fanfix / reader / LocalReaderFrame.java
CommitLineData
a6395bef
NR
1package be.nikiroo.fanfix.reader;
2
d3c84ac3 3import java.awt.BorderLayout;
b4dc6ab5 4import java.awt.Color;
a6395bef 5import java.awt.Desktop;
a6395bef
NR
6import java.awt.event.ActionEvent;
7import java.awt.event.ActionListener;
333f0e7b
NR
8import java.awt.event.KeyEvent;
9import java.awt.event.WindowEvent;
10import java.io.File;
a6395bef 11import java.io.IOException;
333f0e7b 12import java.util.ArrayList;
a6395bef
NR
13import java.util.List;
14
a6395bef 15import javax.swing.JFrame;
333f0e7b
NR
16import javax.swing.JMenu;
17import javax.swing.JMenuBar;
18import javax.swing.JMenuItem;
19import javax.swing.JOptionPane;
20import javax.swing.JPanel;
d3c84ac3 21import javax.swing.JScrollPane;
3b2b638f 22import javax.swing.SwingUtilities;
a6395bef
NR
23
24import be.nikiroo.fanfix.Instance;
b4dc6ab5 25import be.nikiroo.fanfix.bundles.UiConfig;
a6395bef 26import be.nikiroo.fanfix.data.MetaData;
92fb0719 27import be.nikiroo.fanfix.reader.LocalReaderBook.BookActionListener;
3b2b638f
NR
28import be.nikiroo.utils.Progress;
29import be.nikiroo.utils.ui.ProgressBar;
33ab6d12 30import be.nikiroo.utils.ui.WrapLayout;
a6395bef
NR
31
32class 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);
102 Desktop.getDesktop().browse(target.toURI());
103 } catch (IOException e) {
104 Instance.syserr(e);
105 }
106 }
107 });
a6395bef
NR
108 }
109 });
110
333f0e7b 111 bookPane.add(book);
a6395bef
NR
112 }
113
333f0e7b
NR
114 bookPane.validate();
115 bookPane.repaint();
116 }
117
118 private JMenuBar createMenu() {
3b2b638f 119 bar = new JMenuBar();
333f0e7b
NR
120
121 JMenu file = new JMenu("File");
122
123 JMenuItem imprt = new JMenuItem("Import", KeyEvent.VK_I);
124 imprt.addActionListener(new ActionListener() {
125 public void actionPerformed(ActionEvent e) {
3b2b638f
NR
126 final String url = JOptionPane.showInputDialog(
127 LocalReaderFrame.this, "url of the story to import?",
b4dc6ab5
NR
128 "Importing from URL", JOptionPane.QUESTION_MESSAGE);
129 if (url != null && !url.isEmpty()) {
3b2b638f
NR
130 final Progress pg = new Progress("Importing " + url);
131 outOfUi(pg, new Runnable() {
132 public void run() {
133 Exception ex = null;
134 try {
135 Instance.getLibrary().imprt(
136 BasicReader.getUrl(url), pg);
137 } catch (IOException e) {
138 ex = e;
139 }
140
141 final Exception e = ex;
142
143 final boolean ok = (e == null);
144 SwingUtilities.invokeLater(new Runnable() {
145 public void run() {
146 if (!ok) {
147 JOptionPane.showMessageDialog(
148 LocalReaderFrame.this,
149 "Cannot import: " + url,
150 e.getMessage(),
151 JOptionPane.ERROR_MESSAGE);
152
153 setAllEnabled(true);
154 } else {
155 refreshBooks(type);
156 }
157 }
158 });
159 }
160 });
333f0e7b
NR
161 }
162 }
163 });
164 JMenu types = new JMenu("Type");
165 List<String> tt = Instance.getLibrary().getTypes();
166 tt.add(0, null);
167 for (final String type : tt) {
168 JMenuItem item = new JMenuItem(type == null ? "[all]" : type);
169 item.addActionListener(new ActionListener() {
170 public void actionPerformed(ActionEvent e) {
171 refreshBooks(type);
172 }
173 });
174 types.add(item);
175 }
176 JMenuItem exit = new JMenuItem("Exit", KeyEvent.VK_X);
177 exit.addActionListener(new ActionListener() {
178 public void actionPerformed(ActionEvent e) {
179 LocalReaderFrame.this.dispatchEvent(new WindowEvent(
180 LocalReaderFrame.this, WindowEvent.WINDOW_CLOSING));
181 }
182 });
183
184 file.add(imprt);
185 file.add(types);
186 file.addSeparator();
187 file.add(exit);
188
189 bar.add(file);
190
191 return bar;
a6395bef 192 }
3b2b638f
NR
193
194 private void outOfUi(final Progress pg, final Runnable run) {
195 pgBar.setProgress(pg);
196
197 SwingUtilities.invokeLater(new Runnable() {
198 public void run() {
199 setAllEnabled(false);
200 pgBar.addActioListener(new ActionListener() {
201 public void actionPerformed(ActionEvent e) {
202 pgBar.setProgress(null);
203 setAllEnabled(true);
204 }
205 });
206 }
207 });
208
209 new Thread(new Runnable() {
210 public void run() {
211 run.run();
212 if (!pg.isDone()) {
213 pg.setProgress(pg.getMax());
214 }
215 }
216 }).start();
217 }
218
219 public void setAllEnabled(boolean enabled) {
220 for (LocalReaderBook book : books) {
221 book.setEnabled(enabled);
222 book.validate();
223 book.repaint();
224 }
225 bar.setEnabled(enabled);
226 bookPane.setEnabled(enabled);
227 bookPane.validate();
228 bookPane.repaint();
229 setEnabled(enabled);
230 validate();
231 repaint();
232 }
a6395bef 233}