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