1 package be
.nikiroo
.fanfix
.reader
;
3 import java
.awt
.Desktop
;
4 import java
.awt
.EventQueue
;
6 import java
.io
.IOException
;
7 import java
.net
.URISyntaxException
;
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
;
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
;
26 class GuiReader
extends BasicReader
{
27 static private boolean nativeLookLoaded
;
29 private LocalLibrary localLibrary
;
31 public GuiReader() throws IOException
{
32 if (!nativeLookLoaded
) {
33 UIUtils
.setLookAndFeel();
34 nativeLookLoaded
= true;
37 File dir
= Instance
.getReaderDir();
40 throw new IOException(
41 "Cannote create cache directory for local reader: " + dir
);
44 OutputType text
= null;
45 OutputType images
= null;
48 text
= OutputType
.valueOfNullOkUC(Instance
.getUiConfig().getString(
49 UiConfig
.NON_IMAGES_DOCUMENT_TYPE
));
51 text
= OutputType
.HTML
;
54 images
= OutputType
.valueOfNullOkUC(Instance
.getUiConfig()
55 .getString(UiConfig
.IMAGES_DOCUMENT_TYPE
));
57 images
= OutputType
.CBZ
;
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
);
64 throw new IOException(
66 "The configuration option %s is not valid: %s",
70 localLibrary
= new LocalLibrary(dir
, text
, images
);
74 public void read() throws IOException
{
75 MetaData meta
= getMeta();
78 throw new IOException("No story to read");
81 read(meta
.getLuid(), null);
85 * Import the story into the local reader library, and keep the same LUID.
90 * the optional progress reporter
93 * in case of I/O error
95 public void imprt(String luid
, Progress pg
) throws IOException
{
96 Progress pgGetStory
= new Progress();
97 Progress pgSave
= new Progress();
100 pg
.addProgress(pgGetStory
, 1);
101 pg
.addProgress(pgSave
, 1);
105 Story story
= getLibrary().getStory(luid
, pgGetStory
);
107 story
= localLibrary
.save(story
, luid
, pgSave
);
109 throw new IOException("Cannot find story in Library: " + luid
);
111 } catch (IOException e
) {
112 throw new IOException(
113 "Cannot import story from library to LocalReader library: "
119 * Check if the {@link Story} denoted by this Library UID is present in the
120 * {@link GuiReader} cache.
125 * @return TRUE if it is
127 public boolean isCached(String luid
) {
128 return localLibrary
.getInfo(luid
) != null;
132 public void browse(String type
) {
133 // TODO: improve presentation of update message
134 final VersionCheck updates
= VersionCheck
.check();
135 StringBuilder builder
= new StringBuilder();
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>");
149 builder
.append("</ul>");
153 updateMessage
.setText("<html><body>" //
157 // handle link events
158 updateMessage
.addHyperlinkListener(new HyperlinkListener() {
160 public void hyperlinkUpdate(HyperlinkEvent e
) {
161 if (e
.getEventType().equals(
162 HyperlinkEvent
.EventType
.ACTIVATED
))
164 Desktop
.getDesktop().browse(e
.getURL().toURI());
165 } catch (IOException ee
) {
167 } catch (URISyntaxException ee
) {
172 updateMessage
.setEditable(false);
173 updateMessage
.setBackground(new JLabel().getBackground());
176 final String typeFinal
= type
;
177 EventQueue
.invokeLater(new Runnable() {
180 if (updates
.isNewVersionAvailable()) {
181 int rep
= JOptionPane
.showConfirmDialog(null,
182 updateMessage
, "Updates available",
183 JOptionPane
.OK_CANCEL_OPTION
);
184 if (rep
== JOptionPane
.OK_OPTION
) {
191 new GuiReaderFrame(GuiReader
.this, typeFinal
).setVisible(true);
196 // delete from local reader library
197 void clearLocalReaderCache(String luid
) {
199 localLibrary
.delete(luid
);
200 } catch (IOException e
) {
205 // delete from main library
206 void delete(String luid
) {
208 if (localLibrary
.getInfo(luid
) != null) {
209 localLibrary
.delete(luid
);
211 getLibrary().delete(luid
);
212 } catch (IOException e
) {
217 // open the given book
218 void read(String luid
, Progress pg
) throws IOException
{
219 File file
= localLibrary
.getFile(luid
);
222 file
= localLibrary
.getFile(luid
);
225 // TODO: show a special page for the chapter?
226 openExternal(getLibrary().getInfo(luid
), file
);
229 void changeType(String luid
, String newSource
) {
231 if (localLibrary
.getInfo(luid
) != null) {
232 localLibrary
.changeSource(luid
, newSource
, null);
234 getLibrary().changeSource(luid
, newSource
, null);
235 } catch (IOException e
) {