X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Ffanfix%2Freader%2FLocalReaderFrame.java;h=9d39017de82ba212051807934c7951c76070a17a;hb=63985d926fe1649517bc06d8f50761925b4c9984;hp=f196f95e1b8caa38d50f0ed2a2f13e94615f3d37;hpb=a6395bef99a8e917f67341ef1906917b87df24a4;p=fanfix.git diff --git a/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java b/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java index f196f95..9d39017 100644 --- a/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java +++ b/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java @@ -1,55 +1,260 @@ package be.nikiroo.fanfix.reader; +import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Desktop; -import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowEvent; +import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.List; -import javax.swing.JButton; import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.bundles.UiConfig; import be.nikiroo.fanfix.data.MetaData; -import be.nikiroo.fanfix.supported.BasicSupport.SupportType; +import be.nikiroo.fanfix.reader.LocalReaderBook.BookActionListener; +import be.nikiroo.utils.Progress; +import be.nikiroo.utils.ui.ProgressBar; +import be.nikiroo.utils.ui.WrapLayout; class LocalReaderFrame extends JFrame { private static final long serialVersionUID = 1L; private LocalReader reader; + private List stories; + private List books; + private JPanel bookPane; + private String type; + private Color color; + private ProgressBar pgBar; + private JMenuBar bar; - public LocalReaderFrame(LocalReader reader, SupportType type) { - super("HTML reader"); + public LocalReaderFrame(LocalReader reader, String type) { + super("Fanfix Library"); this.reader = reader; setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); - setLayout(new FlowLayout()); + setLayout(new BorderLayout()); - // TODO: list all stories, list all TMP stories (and format?) + books = new ArrayList(); + bookPane = new JPanel(new WrapLayout(WrapLayout.LEADING, 5, 5)); - List stories = Instance.getLibrary().getList(type); - for (MetaData story : stories) { - JButton button = new JButton(story.getTitle()); - final String luid = story.getLuid(); - button.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - try { - // TODO: config option (image, non image): TXT, - // custom-HTML, CBZ, EPUB - Desktop.getDesktop().browse( - LocalReaderFrame.this.reader.getTarget(luid) - .toURI()); - } catch (IOException e1) { - e1.printStackTrace(); + color = Instance.getUiConfig().getColor(UiConfig.BACKGROUND_COLOR); + + if (color != null) { + setBackground(color); + bookPane.setBackground(color); + } + + JScrollPane scroll = new JScrollPane(bookPane); + scroll.getVerticalScrollBar().setUnitIncrement(16); + add(scroll, BorderLayout.CENTER); + + pgBar = new ProgressBar(); + add(pgBar, BorderLayout.SOUTH); + + refreshBooks(type); + setJMenuBar(createMenu()); + + setVisible(true); + } + + private void refreshBooks(String type) { + this.type = type; + stories = Instance.getLibrary().getList(type); + books.clear(); + bookPane.removeAll(); + for (MetaData meta : stories) { + LocalReaderBook book = new LocalReaderBook(meta); + if (color != null) { + book.setBackground(color); + } + + books.add(book); + final String luid = meta.getLuid(); + book.addActionListener(new BookActionListener() { + public void select(LocalReaderBook book) { + for (LocalReaderBook abook : books) { + abook.setSelected(abook == book); } } + + public void action(LocalReaderBook book) { + final Progress pg = new Progress(); + outOfUi(pg, new Runnable() { + public void run() { + try { + File target = LocalReaderFrame.this.reader + .getTarget(luid, pg); + // TODO: allow custom programs, with + // Desktop/xdg-open fallback + try { + Desktop.getDesktop().browse(target.toURI()); + } catch (UnsupportedOperationException e) { + String browsers[] = new String[] { + "xdg-open", "epiphany", + "konqueror", "firefox", "chrome", + "google-chrome", "mozilla" }; + + Runtime runtime = Runtime.getRuntime(); + for (String browser : browsers) { + try { + runtime.exec(new String[] { + browser, + target.getAbsolutePath() }); + runtime = null; + break; + } catch (IOException ioe) { + // continue, try next browser + } + } + + if (runtime != null) { + throw new IOException( + "Cannot find a working GUI browser..."); + } + } + } catch (IOException e) { + Instance.syserr(e); + } + } + }); + } }); - add(button); + bookPane.add(book); } - setVisible(true); + bookPane.validate(); + bookPane.repaint(); + } + + private JMenuBar createMenu() { + bar = new JMenuBar(); + + JMenu file = new JMenu("File"); + + JMenuItem imprt = new JMenuItem("Import", KeyEvent.VK_I); + imprt.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + final String url = JOptionPane.showInputDialog( + LocalReaderFrame.this, "url of the story to import?", + "Importing from URL", JOptionPane.QUESTION_MESSAGE); + if (url != null && !url.isEmpty()) { + final Progress pg = new Progress("Importing " + url); + outOfUi(pg, new Runnable() { + public void run() { + Exception ex = null; + try { + Instance.getLibrary().imprt( + BasicReader.getUrl(url), pg); + } catch (IOException e) { + ex = e; + } + + final Exception e = ex; + + final boolean ok = (e == null); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (!ok) { + JOptionPane.showMessageDialog( + LocalReaderFrame.this, + "Cannot import: " + url, + e.getMessage(), + JOptionPane.ERROR_MESSAGE); + + setAllEnabled(true); + } else { + refreshBooks(type); + } + } + }); + } + }); + } + } + }); + JMenu types = new JMenu("Type"); + List tt = Instance.getLibrary().getTypes(); + tt.add(0, null); + for (final String type : tt) { + JMenuItem item = new JMenuItem(type == null ? "[all]" : type); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + refreshBooks(type); + } + }); + types.add(item); + } + JMenuItem exit = new JMenuItem("Exit", KeyEvent.VK_X); + exit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + LocalReaderFrame.this.dispatchEvent(new WindowEvent( + LocalReaderFrame.this, WindowEvent.WINDOW_CLOSING)); + } + }); + + file.add(imprt); + file.add(types); + file.addSeparator(); + file.add(exit); + + bar.add(file); + + return bar; + } + + private void outOfUi(final Progress pg, final Runnable run) { + pgBar.setProgress(pg); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + setAllEnabled(false); + pgBar.addActioListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + pgBar.setProgress(null); + setAllEnabled(true); + } + }); + } + }); + + new Thread(new Runnable() { + public void run() { + run.run(); + if (!pg.isDone()) { + pg.setProgress(pg.getMax()); + } + } + }).start(); + } + + public void setAllEnabled(boolean enabled) { + for (LocalReaderBook book : books) { + book.setEnabled(enabled); + book.validate(); + book.repaint(); + } + bar.setEnabled(enabled); + bookPane.setEnabled(enabled); + bookPane.validate(); + bookPane.repaint(); + setEnabled(enabled); + validate(); + repaint(); } }