Code cleanup 3 and update jexer-niki :
[fanfix.git] / src / be / nikiroo / fanfix / reader / GuiReader.java
1 package be.nikiroo.fanfix.reader;
2
3 import java.awt.Desktop;
4 import java.awt.EventQueue;
5 import java.io.File;
6 import java.io.IOException;
7 import java.net.URISyntaxException;
8
9 import javax.swing.JEditorPane;
10 import javax.swing.JLabel;
11 import javax.swing.JOptionPane;
12 import javax.swing.event.HyperlinkEvent;
13 import javax.swing.event.HyperlinkListener;
14
15 import be.nikiroo.fanfix.Instance;
16 import be.nikiroo.fanfix.VersionCheck;
17 import be.nikiroo.fanfix.bundles.UiConfig;
18 import be.nikiroo.fanfix.data.MetaData;
19 import be.nikiroo.fanfix.data.Story;
20 import be.nikiroo.fanfix.library.LocalLibrary;
21 import be.nikiroo.fanfix.output.BasicOutput.OutputType;
22 import be.nikiroo.utils.Progress;
23 import be.nikiroo.utils.Version;
24 import be.nikiroo.utils.ui.UIUtils;
25
26 class GuiReader extends BasicReader {
27 static private boolean nativeLookLoaded;
28
29 private LocalLibrary localLibrary;
30
31 public GuiReader() throws IOException {
32 if (!nativeLookLoaded) {
33 UIUtils.setLookAndFeel();
34 nativeLookLoaded = true;
35 }
36
37 File dir = Instance.getReaderDir();
38 dir.mkdirs();
39 if (!dir.exists()) {
40 throw new IOException(
41 "Cannote create cache directory for local reader: " + dir);
42 }
43
44 OutputType text = null;
45 OutputType images = null;
46
47 try {
48 text = OutputType.valueOfNullOkUC(Instance.getUiConfig().getString(
49 UiConfig.NON_IMAGES_DOCUMENT_TYPE));
50 if (text == null) {
51 text = OutputType.HTML;
52 }
53
54 images = OutputType.valueOfNullOkUC(Instance.getUiConfig()
55 .getString(UiConfig.IMAGES_DOCUMENT_TYPE));
56 if (images == null) {
57 images = OutputType.CBZ;
58 }
59 } catch (Exception e) {
60 UiConfig key = (text == null) ? UiConfig.NON_IMAGES_DOCUMENT_TYPE
61 : UiConfig.IMAGES_DOCUMENT_TYPE;
62 String value = Instance.getUiConfig().getString(key);
63
64 throw new IOException(
65 String.format(
66 "The configuration option %s is not valid: %s",
67 key, value), e);
68 }
69
70 localLibrary = new LocalLibrary(dir, text, images);
71 }
72
73 public void read() throws IOException {
74 MetaData meta = getMeta();
75
76 if (meta == null) {
77 throw new IOException("No story to read");
78 }
79
80 read(meta.getLuid(), null);
81 }
82
83 /**
84 * Import the story into the local reader library, and keep the same LUID.
85 *
86 * @param luid
87 * the Library UID
88 * @param pg
89 * the optional progress reporter
90 *
91 * @throws IOException
92 * in case of I/O error
93 */
94 public void imprt(String luid, Progress pg) throws IOException {
95 Progress pgGetStory = new Progress();
96 Progress pgSave = new Progress();
97 if (pg != null) {
98 pg.setMax(2);
99 pg.addProgress(pgGetStory, 1);
100 pg.addProgress(pgSave, 1);
101 }
102
103 try {
104 Story story = getLibrary().getStory(luid, pgGetStory);
105 if (story != null) {
106 story = localLibrary.save(story, luid, pgSave);
107 } else {
108 throw new IOException("Cannot find story in Library: " + luid);
109 }
110 } catch (IOException e) {
111 throw new IOException(
112 "Cannot import story from library to LocalReader library: "
113 + luid, e);
114 }
115 }
116
117 /**
118 * Check if the {@link Story} denoted by this Library UID is present in the
119 * {@link GuiReader} cache.
120 *
121 * @param luid
122 * the Library UID
123 *
124 * @return TRUE if it is
125 */
126 public boolean isCached(String luid) {
127 return localLibrary.getInfo(luid) != null;
128 }
129
130 public void browse(String type) {
131 // TODO: improve presentation of update message
132 final VersionCheck updates = VersionCheck.check();
133 StringBuilder builder = new StringBuilder();
134
135 final JEditorPane updateMessage = new JEditorPane("text/html", "");
136 if (updates.isNewVersionAvailable()) {
137 builder.append("A new version of the program is available at <span style='color: blue;'>https://github.com/nikiroo/fanfix/releases</span>");
138 builder.append("<br>");
139 builder.append("<br>");
140 for (Version v : updates.getNewer()) {
141 builder.append("\t<b>Version " + v + "</b>");
142 builder.append("<br>");
143 builder.append("<ul>");
144 for (String item : updates.getChanges().get(v)) {
145 builder.append("<li>" + item + "</li>");
146 }
147 builder.append("</ul>");
148 }
149
150 // html content
151 updateMessage.setText("<html><body>" //
152 + builder//
153 + "</body></html>");
154
155 // handle link events
156 updateMessage.addHyperlinkListener(new HyperlinkListener() {
157 public void hyperlinkUpdate(HyperlinkEvent e) {
158 if (e.getEventType().equals(
159 HyperlinkEvent.EventType.ACTIVATED))
160 try {
161 Desktop.getDesktop().browse(e.getURL().toURI());
162 } catch (IOException ee) {
163 Instance.syserr(ee);
164 } catch (URISyntaxException ee) {
165 Instance.syserr(ee);
166 }
167 }
168 });
169 updateMessage.setEditable(false);
170 updateMessage.setBackground(new JLabel().getBackground());
171 }
172
173 final String typeFinal = type;
174 EventQueue.invokeLater(new Runnable() {
175 public void run() {
176 if (updates.isNewVersionAvailable()) {
177 int rep = JOptionPane.showConfirmDialog(null,
178 updateMessage, "Updates available",
179 JOptionPane.OK_CANCEL_OPTION);
180 if (rep == JOptionPane.OK_OPTION) {
181 updates.ok();
182 } else {
183 updates.ignore();
184 }
185 }
186
187 new GuiReaderFrame(GuiReader.this, typeFinal).setVisible(true);
188 }
189 });
190 }
191
192 // delete from local reader library
193 void clearLocalReaderCache(String luid) {
194 try {
195 localLibrary.delete(luid);
196 } catch (IOException e) {
197 Instance.syserr(e);
198 }
199 }
200
201 // delete from main library
202 void delete(String luid) {
203 try {
204 localLibrary.delete(luid);
205 getLibrary().delete(luid);
206 } catch (IOException e) {
207 Instance.syserr(e);
208 }
209 }
210
211 // open the given book
212 void read(String luid, Progress pg) throws IOException {
213 File file = localLibrary.getFile(luid);
214 if (file == null) {
215 imprt(luid, pg);
216 file = localLibrary.getFile(luid);
217 }
218
219 // TODO: show a special page for the chapter?
220 openExternal(getLibrary().getInfo(luid), file);
221 }
222
223 void changeType(String luid, String newSource) {
224 try {
225 localLibrary.changeSource(luid, newSource, null);
226 getLibrary().changeSource(luid, newSource, null);
227 } catch (IOException e) {
228 Instance.syserr(e);
229 }
230 }
231 }