410e05e56f0cd3a05338c8d37f6633e488cbb075
[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.utils.Progress;
22 import be.nikiroo.utils.Version;
23 import be.nikiroo.utils.ui.UIUtils;
24
25 class GuiReader extends BasicReader {
26 static private boolean nativeLookLoaded;
27
28 private LocalLibrary localLibrary;
29
30 public GuiReader() throws IOException {
31 if (!nativeLookLoaded) {
32 UIUtils.setLookAndFeel();
33 nativeLookLoaded = true;
34 }
35
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
43 localLibrary = new LocalLibrary(dir, Instance.getUiConfig().getString(
44 UiConfig.GUI_NON_IMAGES_DOCUMENT_TYPE), Instance.getUiConfig()
45 .getString(UiConfig.GUI_IMAGES_DOCUMENT_TYPE), true);
46 }
47
48 @Override
49 public void read() throws IOException {
50 MetaData meta = getMeta();
51
52 if (meta == null) {
53 throw new IOException("No story to read");
54 }
55
56 read(meta.getLuid(), null);
57 }
58
59 /**
60 * Import the story into the local reader library, and keep the same LUID.
61 *
62 * @param luid
63 * the Library UID
64 * @param pg
65 * the optional progress reporter
66 *
67 * @throws IOException
68 * in case of I/O error
69 */
70 public void imprt(String luid, Progress pg) throws IOException {
71 try {
72 localLibrary.imprt(getLibrary(), luid, pg);
73 } catch (IOException e) {
74 throw new IOException(
75 "Cannot import story from library to LocalReader library: "
76 + luid, e);
77 }
78 }
79
80 /**
81 * Check if the {@link Story} denoted by this Library UID is present in the
82 * {@link GuiReader} cache.
83 *
84 * @param luid
85 * the Library UID
86 *
87 * @return TRUE if it is
88 */
89 public boolean isCached(String luid) {
90 return localLibrary.getInfo(luid) != null;
91 }
92
93 @Override
94 public void browse(String type) {
95 // TODO: improve presentation of update message
96 final VersionCheck updates = VersionCheck.check();
97 StringBuilder builder = new StringBuilder();
98
99 final JEditorPane updateMessage = new JEditorPane("text/html", "");
100 if (updates.isNewVersionAvailable()) {
101 builder.append("A new version of the program is available at <span style='color: blue;'>https://github.com/nikiroo/fanfix/releases</span>");
102 builder.append("<br>");
103 builder.append("<br>");
104 for (Version v : updates.getNewer()) {
105 builder.append("\t<b>Version " + v + "</b>");
106 builder.append("<br>");
107 builder.append("<ul>");
108 for (String item : updates.getChanges().get(v)) {
109 builder.append("<li>" + item + "</li>");
110 }
111 builder.append("</ul>");
112 }
113
114 // html content
115 updateMessage.setText("<html><body>" //
116 + builder//
117 + "</body></html>");
118
119 // handle link events
120 updateMessage.addHyperlinkListener(new HyperlinkListener() {
121 @Override
122 public void hyperlinkUpdate(HyperlinkEvent e) {
123 if (e.getEventType().equals(
124 HyperlinkEvent.EventType.ACTIVATED))
125 try {
126 Desktop.getDesktop().browse(e.getURL().toURI());
127 } catch (IOException ee) {
128 Instance.syserr(ee);
129 } catch (URISyntaxException ee) {
130 Instance.syserr(ee);
131 }
132 }
133 });
134 updateMessage.setEditable(false);
135 updateMessage.setBackground(new JLabel().getBackground());
136 }
137
138 final String typeFinal = type;
139 EventQueue.invokeLater(new Runnable() {
140 @Override
141 public void run() {
142 if (updates.isNewVersionAvailable()) {
143 int rep = JOptionPane.showConfirmDialog(null,
144 updateMessage, "Updates available",
145 JOptionPane.OK_CANCEL_OPTION);
146 if (rep == JOptionPane.OK_OPTION) {
147 updates.ok();
148 } else {
149 updates.ignore();
150 }
151 }
152
153 new GuiReaderFrame(GuiReader.this, typeFinal).setVisible(true);
154 }
155 });
156 }
157
158 // delete from local reader library
159 void clearLocalReaderCache(String luid) {
160 try {
161 localLibrary.delete(luid);
162 } catch (IOException e) {
163 Instance.syserr(e);
164 }
165 }
166
167 // delete from main library
168 void delete(String luid) {
169 try {
170 if (localLibrary.getInfo(luid) != null) {
171 localLibrary.delete(luid);
172 }
173 getLibrary().delete(luid);
174 } catch (IOException e) {
175 Instance.syserr(e);
176 }
177 }
178
179 // open the given book
180 void read(String luid, Progress pg) throws IOException {
181 File file = localLibrary.getFile(luid);
182 if (file == null) {
183 imprt(luid, pg);
184 file = localLibrary.getFile(luid);
185 }
186
187 // TODO: show a special page for the chapter?
188 openExternal(getLibrary().getInfo(luid), file);
189 }
190
191 void changeType(String luid, String newSource) {
192 try {
193 if (localLibrary.getInfo(luid) != null) {
194 localLibrary.changeSource(luid, newSource, null);
195 }
196 getLibrary().changeSource(luid, newSource, null);
197 } catch (IOException e) {
198 Instance.syserr(e);
199 }
200 }
201 }