beta option: download url
[fanfix.git] / src / be / nikiroo / fanfix_swing / Actions.java
CommitLineData
3cdf3fd8
NR
1package be.nikiroo.fanfix_swing;
2
3import java.awt.BorderLayout;
4import java.awt.Container;
04eafeea 5import java.awt.Toolkit;
3cdf3fd8 6import java.awt.Window;
04eafeea 7import java.awt.datatransfer.DataFlavor;
3cdf3fd8
NR
8import java.io.File;
9import java.io.IOException;
04eafeea
NR
10import java.net.URL;
11import java.net.UnknownHostException;
3cdf3fd8
NR
12
13import javax.swing.JDialog;
04eafeea 14import javax.swing.JFileChooser;
3cdf3fd8 15import javax.swing.JLabel;
04eafeea 16import javax.swing.JOptionPane;
3cdf3fd8
NR
17import javax.swing.SwingWorker;
18
19import be.nikiroo.fanfix.Instance;
04eafeea 20import be.nikiroo.fanfix.bundles.StringIdGui;
3cdf3fd8
NR
21import be.nikiroo.fanfix.bundles.UiConfig;
22import be.nikiroo.fanfix.data.MetaData;
23import be.nikiroo.fanfix.data.Story;
24import be.nikiroo.fanfix.library.BasicLibrary;
04eafeea
NR
25import be.nikiroo.fanfix.library.LocalLibrary;
26import be.nikiroo.fanfix.reader.BasicReader;
59253323 27import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
04eafeea 28import be.nikiroo.utils.Progress;
3cdf3fd8
NR
29
30public class Actions {
59253323
NR
31 static public void openExternal(final BasicLibrary lib, MetaData meta, final Container parent,
32 final Runnable onDone) {
33 Container parentWindow = parent;
34 while (!(parentWindow instanceof Window) && parentWindow != null) {
35 parentWindow = parentWindow.getParent();
3cdf3fd8
NR
36 }
37
38 // TODO: UI
59253323 39 final JDialog wait = new JDialog((Window) parentWindow);
3cdf3fd8
NR
40 wait.setTitle("Opening story");
41 wait.setSize(400, 300);
42 wait.setLayout(new BorderLayout());
43 wait.add(new JLabel("Waiting..."));
44
45 // TODO: pg?
46
47 final Object waitLock = new Object();
48 final Boolean[] waitScreen = new Boolean[] { false };
49 new Thread(new Runnable() {
50 @Override
51 public void run() {
52 try {
53 Thread.sleep(200);
54 } catch (InterruptedException e) {
55 }
56
57 synchronized (waitLock) {
58 if (!waitScreen[0]) {
59 waitScreen[0] = true;
60 wait.setVisible(true);
61 }
62 }
63 }
64 }).start();
65
66 final String luid = meta.getLuid();
67 final boolean isImageDocument = meta.isImageDocument();
68
69 final SwingWorker<File, Void> worker = new SwingWorker<File, Void>() {
70 private File target;
71
72 @Override
73 protected File doInBackground() throws Exception {
74 target = lib.getFile(luid, null);
75 return null;
76 }
77
78 @Override
79 protected void done() {
80 try {
59253323 81 get();
3cdf3fd8 82 openExternal(target, isImageDocument);
59253323
NR
83 } catch (Exception e) {
84 // TODO: i18n
85 UiHelper.error(parent, e.getLocalizedMessage(), "Cannot open the story", e);
3cdf3fd8
NR
86 }
87
88 synchronized (waitLock) {
89 if (waitScreen[0]) {
90 wait.setVisible(false);
91 }
92 waitScreen[0] = true;
93 }
94
95 if (onDone != null) {
96 onDone.run();
97 }
98 }
99 };
100
101 worker.execute();
102 }
103
104 /**
105 * Open the {@link Story} with an external reader (the program will be passed
106 * the given target file).
107 *
108 * @param target the target {@link File}
109 * @param isImageDocument TRUE for image documents, FALSE for not-images
110 * documents
111 *
112 * @throws IOException in case of I/O error
113 */
114 static public void openExternal(File target, boolean isImageDocument) throws IOException {
115 String program = null;
116 if (isImageDocument) {
117 program = Instance.getInstance().getUiConfig().getString(UiConfig.IMAGES_DOCUMENT_READER);
118 } else {
119 program = Instance.getInstance().getUiConfig().getString(UiConfig.NON_IMAGES_DOCUMENT_READER);
120 }
121
122 if (program != null && program.trim().isEmpty()) {
123 program = null;
124 }
125
126 start(target, program, false);
127 }
128
129 /**
130 * Start a file and open it with the given program if given or the first default
131 * system starter we can find.
132 *
133 * @param target the target to open
134 * @param program the program to use or NULL for the default system starter
135 * @param sync execute the process synchronously (wait until it is terminated
136 * before returning)
137 *
138 * @throws IOException in case of I/O error
139 */
140 static protected void start(File target, String program, boolean sync) throws IOException {
141 Process proc = null;
142 if (program == null) {
143 boolean ok = false;
144 for (String starter : new String[] { "xdg-open", "open", "see", "start", "run" }) {
145 try {
146 Instance.getInstance().getTraceHandler().trace("starting external program");
147 proc = Runtime.getRuntime().exec(new String[] { starter, target.getAbsolutePath() });
148 ok = true;
149 break;
150 } catch (IOException e) {
151 }
152 }
153 if (!ok) {
154 throw new IOException("Cannot find a program to start the file");
155 }
156 } else {
157 Instance.getInstance().getTraceHandler().trace("starting external program");
158 proc = Runtime.getRuntime().exec(new String[] { program, target.getAbsolutePath() });
159 }
160
161 if (proc != null && sync) {
162 try {
163 proc.waitFor();
164 } catch (InterruptedException e) {
165 }
166 }
167 }
04eafeea
NR
168
169 /**
170 * Import a {@link Story} into the main {@link LocalLibrary}.
171 * <p>
172 * Should be called inside the UI thread.
173 *
174 * @param askUrl TRUE for an {@link URL}, false for a {@link File}
175 */
176 static public void imprt(final Container parent, boolean askUrl, final Runnable onSuccess) {
177 JFileChooser fc = new JFileChooser();
178
179 Object url;
180 if (askUrl) {
181 String clipboard = "";
182 try {
183 clipboard = ("" + Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor))
184 .trim();
185 } catch (Exception e) {
186 // No data will be handled
187 }
188
189 if (clipboard == null || !(clipboard.startsWith("http://") || //
190 clipboard.startsWith("https://"))) {
191 clipboard = "";
192 }
193
194 url = JOptionPane.showInputDialog(parent,
195 Instance.getInstance().getTransGui().getString(StringIdGui.SUBTITLE_IMPORT_URL),
196 Instance.getInstance().getTransGui().getString(StringIdGui.TITLE_IMPORT_URL),
197 JOptionPane.QUESTION_MESSAGE, null, null, clipboard);
198 } else if (fc.showOpenDialog(parent) != JFileChooser.CANCEL_OPTION) {
199 url = fc.getSelectedFile().getAbsolutePath();
200 } else {
201 url = null;
202 }
203
204 if (url != null && !url.toString().isEmpty()) {
205 imprt(parent, url.toString(), null, null);
206 }
207 }
208
209 /**
210 * Actually import the {@link Story} into the main {@link LocalLibrary}.
211 * <p>
212 * Should be called inside the UI thread.
213 *
214 * @param url the {@link Story} to import by {@link URL}
215 * @param onSuccess Action to execute on success
216 * @param onSuccessPgName the name to use for the onSuccess progress bar
217 */
218 static public void imprt(final Container parent, final String url, final Runnable onSuccess,
219 String onSuccessPgName) {
220 final Progress pg = new Progress();
221 final Progress pgImprt = new Progress();
222 final Progress pgOnSuccess = new Progress(onSuccessPgName);
223 pg.addProgress(pgImprt, 95);
224 pg.addProgress(pgOnSuccess, 5);
225
226 new SwingWorker<Void, Void>() {
227 @Override
228 protected Void doInBackground() throws Exception {
229 Exception ex = null;
230 MetaData meta = null;
231 try {
232 meta = Instance.getInstance().getLibrary().imprt(BasicReader.getUrl(url), pgImprt);
233 } catch (IOException e) {
234 e.printStackTrace();
235 ex = e;
236 }
237
238 final Exception e = ex;
239
240 final boolean ok = (e == null);
241
242 pgOnSuccess.setProgress(0);
243 if (!ok) {
244 if (e instanceof UnknownHostException) {
245 UiHelper.error(parent,
246 Instance.getInstance().getTransGui().getString(StringIdGui.ERROR_URL_NOT_SUPPORTED,
247 url),
248 Instance.getInstance().getTransGui().getString(StringIdGui.TITLE_ERROR), null);
249 } else {
250 UiHelper.error(parent,
251 Instance.getInstance().getTransGui().getString(StringIdGui.ERROR_URL_IMPORT_FAILED, url,
252 e.getMessage()),
253 Instance.getInstance().getTransGui().getString(StringIdGui.TITLE_ERROR), e);
254 }
255 } else {
256 if (onSuccess != null) {
257 onSuccess.run();
258 }
259 }
260 pgOnSuccess.done();
261
262 return null;
263 }
264 }.execute();
265 }
3cdf3fd8 266}