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
.Library
;
17 import be
.nikiroo
.fanfix
.VersionCheck
;
18 import be
.nikiroo
.fanfix
.bundles
.UiConfig
;
19 import be
.nikiroo
.fanfix
.data
.MetaData
;
20 import be
.nikiroo
.fanfix
.data
.Story
;
21 import be
.nikiroo
.fanfix
.output
.BasicOutput
.OutputType
;
22 import be
.nikiroo
.utils
.Progress
;
23 import be
.nikiroo
.utils
.Version
;
25 class LocalReader
extends BasicReader
{
28 public LocalReader() throws IOException
{
29 File dir
= Instance
.getReaderDir();
32 throw new IOException(
33 "Cannote create cache directory for local reader: " + dir
);
36 OutputType text
= null;
37 OutputType images
= null;
40 text
= OutputType
.valueOfNullOkUC(Instance
.getUiConfig().getString(
41 UiConfig
.NON_IMAGES_DOCUMENT_TYPE
));
43 text
= OutputType
.HTML
;
46 images
= OutputType
.valueOfNullOkUC(Instance
.getUiConfig()
47 .getString(UiConfig
.IMAGES_DOCUMENT_TYPE
));
49 images
= OutputType
.CBZ
;
51 } catch (Exception e
) {
52 UiConfig key
= (text
== null) ? UiConfig
.NON_IMAGES_DOCUMENT_TYPE
53 : UiConfig
.IMAGES_DOCUMENT_TYPE
;
54 String value
= Instance
.getUiConfig().getString(key
);
56 throw new IOException(
58 "The configuration option %s is not valid: %s",
62 lib
= new Library(dir
, text
, images
);
66 public void read() throws IOException
{
67 if (getStory() == null) {
68 throw new IOException("No story to read");
71 open(getStory().getMeta().getLuid(), null);
75 public void read(int chapter
) throws IOException
{
76 // TODO: show a special page?
81 * Import the story into the local reader library, and keep the same LUID.
86 * the optional progress reporter
89 * in case of I/O error
91 public void imprt(String luid
, Progress pg
) throws IOException
{
92 Progress pgGetStory
= new Progress();
93 Progress pgSave
= new Progress();
96 pg
.addProgress(pgGetStory
, 1);
97 pg
.addProgress(pgSave
, 1);
101 Story story
= Instance
.getLibrary().getStory(luid
, pgGetStory
);
103 story
= lib
.save(story
, luid
, pgSave
);
105 throw new IOException("Cannot find story in Library: " + luid
);
107 } catch (IOException e
) {
108 throw new IOException(
109 "Cannot import story from library to LocalReader library: "
115 * Get the target file related to this {@link Story}.
118 * the LUID of the {@link Story}
120 * the optional progress reporter
122 * @return the target file
124 * @throws IOException
125 * in case of I/O error
127 public File
getTarget(String luid
, Progress pg
) throws IOException
{
128 File file
= lib
.getFile(luid
);
131 file
= lib
.getFile(luid
);
138 * Check if the {@link Story} denoted by this Library UID is present in the
139 * {@link LocalReader} cache.
144 * @return TRUE if it is
146 public boolean isCached(String luid
) {
147 return lib
.getInfo(luid
) != null;
151 public void start(String type
) {
152 // TODO: improve presentation of update message
153 final VersionCheck updates
= VersionCheck
.check();
154 StringBuilder builder
= new StringBuilder();
156 final JEditorPane updateMessage
= new JEditorPane("text/html", "");
157 if (updates
.isNewVersionAvailable()) {
158 builder
.append("A new version of the program is available at <span style='color: blue;'>https://github.com/nikiroo/fanfix/releases</span>");
159 builder
.append("<br>");
160 builder
.append("<br>");
161 for (Version v
: updates
.getNewer()) {
162 builder
.append("\t<b>Version " + v
+ "</b>");
163 builder
.append("<br>");
164 builder
.append("<ul>");
165 for (String item
: updates
.getChanges().get(v
)) {
166 builder
.append("<li>" + item
+ "</li>");
168 builder
.append("</ul>");
172 updateMessage
.setText("<html><body>" //
176 // handle link events
177 updateMessage
.addHyperlinkListener(new HyperlinkListener() {
178 public void hyperlinkUpdate(HyperlinkEvent e
) {
179 if (e
.getEventType().equals(
180 HyperlinkEvent
.EventType
.ACTIVATED
))
182 Desktop
.getDesktop().browse(e
.getURL().toURI());
183 } catch (IOException ee
) {
185 } catch (URISyntaxException ee
) {
190 updateMessage
.setEditable(false);
191 updateMessage
.setBackground(new JLabel().getBackground());
194 final String typeFinal
= type
;
195 EventQueue
.invokeLater(new Runnable() {
197 if (updates
.isNewVersionAvailable()) {
198 int rep
= JOptionPane
.showConfirmDialog(null,
199 updateMessage
, "Updates available",
200 JOptionPane
.OK_CANCEL_OPTION
);
201 if (rep
== JOptionPane
.OK_OPTION
) {
208 new LocalReaderFrame(LocalReader
.this, typeFinal
)
214 // delete from local reader library
215 void clearLocalReaderCache(String luid
) {
219 // delete from main library
220 void delete(String luid
) {
222 Instance
.getLibrary().delete(luid
);
225 // open the given book
226 void open(String luid
, Progress pg
) throws IOException
{
227 MetaData meta
= Instance
.getLibrary().getInfo(luid
);
228 File target
= getTarget(luid
, pg
);
230 String program
= null;
231 if (meta
.isImageDocument()) {
232 program
= Instance
.getUiConfig().getString(
233 UiConfig
.IMAGES_DOCUMENT_READER
);
235 program
= Instance
.getUiConfig().getString(
236 UiConfig
.NON_IMAGES_DOCUMENT_READER
);
239 if (program
!= null && program
.trim().isEmpty()) {
243 if (program
== null) {
245 Desktop
.getDesktop().browse(target
.toURI());
246 } catch (UnsupportedOperationException e
) {
247 Runtime
.getRuntime().exec(
248 new String
[] { "xdg-open", target
.getAbsolutePath() });
252 Runtime
.getRuntime().exec(
253 new String
[] { program
, target
.getAbsolutePath() });