import javax.swing.filechooser.FileNameExtensionFilter;
import be.nikiroo.fanfix.Instance;
-import be.nikiroo.fanfix.LocalLibrary;
import be.nikiroo.fanfix.bundles.Config;
import be.nikiroo.fanfix.bundles.UiConfig;
import be.nikiroo.fanfix.data.MetaData;
import be.nikiroo.fanfix.data.Story;
+import be.nikiroo.fanfix.library.LocalLibrary;
import be.nikiroo.fanfix.output.BasicOutput.OutputType;
import be.nikiroo.fanfix.reader.GuiReaderBook.BookActionListener;
import be.nikiroo.utils.Progress;
private GuiReaderBook selectedBook;
private boolean words; // words or authors (secondary info on books)
+ /**
+ * A {@link Runnable} with a {@link Story} parameter.
+ *
+ * @author niki
+ */
+ private interface StoryRunnable {
+ /**
+ * Run the action.
+ *
+ * @param story
+ * the story
+ */
+ public void run(Story story);
+ }
+
/**
* Create a new {@link GuiReaderFrame}.
*
add(pgBar, BorderLayout.SOUTH);
pgBar.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
invalidate();
pgBar.setProgress(null);
});
pgBar.addUpdateListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
invalidate();
validate();
final Progress pg = new Progress();
final String typeF = type;
outOfUi(pg, new Runnable() {
+ @Override
public void run() {
- Instance.getLibrary().refresh(false, pg);
+ GuiReaderFrame.this.reader.getLibrary().refresh(false, pg);
invalidate();
setJMenuBar(createMenu());
addBookPane(typeF, true);
setVisible(true);
}
+ private void addSourcePanes() {
+ // Sources -> i18n
+ GuiReaderGroup bookPane = new GuiReaderGroup(reader, "Sources", color);
+
+ List<MetaData> sources = new ArrayList<MetaData>();
+ for (String source : reader.getLibrary().getSources()) {
+ MetaData mSource = new MetaData();
+ mSource.setLuid(null);
+ mSource.setTitle(source);
+ mSource.setSource(source);
+ sources.add(mSource);
+ }
+
+ bookPane.refreshBooks(sources, false);
+
+ this.invalidate();
+ pane.invalidate();
+ pane.add(bookPane);
+ pane.validate();
+ this.validate();
+
+ bookPane.setActionListener(new BookActionListener() {
+ @Override
+ public void select(GuiReaderBook book) {
+ selectedBook = book;
+ }
+
+ @Override
+ public void popupRequested(GuiReaderBook book, MouseEvent e) {
+ JPopupMenu popup = new JPopupMenu();
+ popup.add(createMenuItemOpenBook());
+ popup.show(e.getComponent(), e.getX(), e.getY());
+ }
+
+ @Override
+ public void action(final GuiReaderBook book) {
+ removeBookPanes();
+ addBookPane(book.getMeta().getSource(), true);
+ refreshBooks();
+ }
+ });
+ }
+
/**
* Add a new {@link GuiReaderGroup} on the frame to display the books of the
* selected type or author.
private void addBookPane(String value, boolean type) {
if (value == null) {
if (type) {
- for (String tt : Instance.getLibrary().getSources()) {
- if (tt != null) {
- addBookPane(tt, type);
+ if (Instance.getUiConfig().getBoolean(UiConfig.SOURCE_PAGE,
+ false)) {
+ addSourcePanes();
+ } else {
+ for (String tt : reader.getLibrary().getSources()) {
+ if (tt != null) {
+ addBookPane(tt, type);
+ }
}
}
} else {
- for (String tt : Instance.getLibrary().getAuthors()) {
+ for (String tt : reader.getLibrary().getAuthors()) {
if (tt != null) {
addBookPane(tt, type);
}
this.validate();
bookPane.setActionListener(new BookActionListener() {
+ @Override
public void select(GuiReaderBook book) {
selectedBook = book;
}
+ @Override
public void popupRequested(GuiReaderBook book, MouseEvent e) {
JPopupMenu popup = new JPopupMenu();
popup.add(createMenuItemOpenBook());
popup.addSeparator();
popup.add(createMenuItemExport());
popup.add(createMenuItemMove());
+ popup.add(createMenuItemSetCover());
popup.add(createMenuItemClearCache());
popup.add(createMenuItemRedownload());
popup.addSeparator();
popup.show(e.getComponent(), e.getX(), e.getY());
}
+ @Override
public void action(final GuiReaderBook book) {
openBook(book);
}
*/
private void refreshBooks() {
for (GuiReaderGroup group : booksByType.keySet()) {
- List<MetaData> stories = Instance.getLibrary().getListBySource(
+ List<MetaData> stories = reader.getLibrary().getListBySource(
booksByType.get(group));
group.refreshBooks(stories, words);
}
for (GuiReaderGroup group : booksByAuthor.keySet()) {
- List<MetaData> stories = Instance.getLibrary().getListByAuthor(
+ List<MetaData> stories = reader.getLibrary().getListByAuthor(
booksByAuthor.get(group));
group.refreshBooks(stories, words);
}
JMenuItem imprt = new JMenuItem("Import URL...", KeyEvent.VK_U);
imprt.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
imprt(true);
}
});
JMenuItem imprtF = new JMenuItem("Import File...", KeyEvent.VK_F);
imprtF.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
imprt(false);
}
});
JMenuItem exit = new JMenuItem("Exit", KeyEvent.VK_X);
exit.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
GuiReaderFrame.this.dispatchEvent(new WindowEvent(
GuiReaderFrame.this, WindowEvent.WINDOW_CLOSING));
JMenuItem vauthors = new JMenuItem("Author");
vauthors.setMnemonic(KeyEvent.VK_A);
vauthors.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
words = false;
refreshBooks();
JMenuItem vwords = new JMenuItem("Word count");
vwords.setMnemonic(KeyEvent.VK_W);
vwords.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
words = true;
refreshBooks();
JMenu sources = new JMenu("Sources");
sources.setMnemonic(KeyEvent.VK_S);
- List<String> tt = Instance.getLibrary().getSources();
+ List<String> tt = reader.getLibrary().getSources();
tt.add(0, null);
for (final String type : tt) {
JMenuItem item = new JMenuItem(type == null ? "All" : type);
item.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
removeBookPanes();
addBookPane(type, true);
JMenu authors = new JMenu("Authors");
authors.setMnemonic(KeyEvent.VK_A);
- List<String> aa = Instance.getLibrary().getAuthors();
+ List<String> aa = reader.getLibrary().getAuthors();
aa.add(0, null);
for (final String author : aa) {
JMenuItem item = new JMenuItem(author == null ? "All"
: author.isEmpty() ? "[unknown]" : author);
item.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
removeBookPanes();
addBookPane(author, false);
item.setMnemonic(KeyEvent.VK_F);
item.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
ConfigEditor<Config> ed = new ConfigEditor<Config>(
Config.class, Instance.getConfig(),
item.setMnemonic(KeyEvent.VK_U);
item.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
ConfigEditor<UiConfig> ed = new ConfigEditor<UiConfig>(
UiConfig.class, Instance.getUiConfig(),
JMenuItem export = new JMenuItem("Save as...", KeyEvent.VK_S);
export.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
if (selectedBook != null) {
fc.showDialog(GuiReaderFrame.this, "Save");
+ type.getDefaultExtension(false);
final Progress pg = new Progress();
outOfUi(pg, new Runnable() {
+ @Override
public void run() {
try {
- Instance.getLibrary().export(
+ reader.getLibrary().export(
selectedBook.getMeta().getLuid(),
type, path, pg);
} catch (IOException e) {
private JMenuItem createMenuItemClearCache() {
JMenuItem refresh = new JMenuItem("Clear cache", KeyEvent.VK_C);
refresh.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
if (selectedBook != null) {
outOfUi(null, new Runnable() {
+ @Override
public void run() {
reader.clearLocalReaderCache(selectedBook.getMeta()
.getLuid());
selectedBook.setCached(false);
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
selectedBook.repaint();
}
List<String> types = new ArrayList<String>();
types.add(null);
- types.addAll(Instance.getLibrary().getSources());
+ types.addAll(reader.getLibrary().getSources());
for (String type : types) {
JMenuItem item = new JMenuItem(type == null ? "New type..." : type);
final String ftype = type;
item.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
if (selectedBook != null) {
String type = ftype;
"Moving story",
JOptionPane.QUESTION_MESSAGE, null, null,
selectedBook.getMeta().getSource());
+
if (rep == null) {
return;
- } else {
- type = rep.toString();
}
+
+ type = rep.toString();
}
final String ftype = type;
outOfUi(null, new Runnable() {
+ @Override
public void run() {
reader.changeType(selectedBook.getMeta()
.getLuid(), ftype);
selectedBook = null;
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
setJMenuBar(createMenu());
}
private JMenuItem createMenuItemRedownload() {
JMenuItem refresh = new JMenuItem("Redownload", KeyEvent.VK_R);
refresh.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
if (selectedBook != null) {
final MetaData meta = selectedBook.getMeta();
- imprt(meta.getUrl(), new Runnable() {
- public void run() {
+ imprt(meta.getUrl(), new StoryRunnable() {
+ @Override
+ public void run(Story story) {
reader.delete(meta.getLuid());
GuiReaderFrame.this.selectedBook = null;
+ MetaData newMeta = story.getMeta();
+ if (!newMeta.getSource().equals(meta.getSource())) {
+ reader.changeType(newMeta.getLuid(),
+ meta.getSource());
+ }
}
}, "Removing old copy");
}
private JMenuItem createMenuItemDelete() {
JMenuItem delete = new JMenuItem("Delete", KeyEvent.VK_D);
delete.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
if (selectedBook != null) {
outOfUi(null, new Runnable() {
+ @Override
public void run() {
reader.delete(selectedBook.getMeta().getLuid());
selectedBook = null;
}
/**
- * Create the open menu item.
+ * Create the open menu item for a book or a source (no LUID).
*
* @return the item
*/
private JMenuItem createMenuItemOpenBook() {
JMenuItem open = new JMenuItem("Open", KeyEvent.VK_O);
open.addActionListener(new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
if (selectedBook != null) {
- openBook(selectedBook);
+ if (selectedBook.getMeta().getLuid() == null) {
+ removeBookPanes();
+ addBookPane(selectedBook.getMeta().getSource(), true);
+ refreshBooks();
+ } else {
+ openBook(selectedBook);
+ }
+ }
+ }
+ });
+
+ return open;
+ }
+
+ /**
+ * Create the SetCover menu item for a book to change the linked source
+ * cover.
+ *
+ * @return the item
+ */
+ private JMenuItem createMenuItemSetCover() {
+ JMenuItem open = new JMenuItem("Set as cover for source", KeyEvent.VK_C);
+ open.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (selectedBook != null) {
+ reader.getLibrary().setSourceCover(
+ selectedBook.getMeta().getSource(),
+ selectedBook.getMeta().getLuid());
}
}
});
private void openBook(final GuiReaderBook book) {
final Progress pg = new Progress();
outOfUi(pg, new Runnable() {
+ @Override
public void run() {
try {
- reader.open(book.getMeta().getLuid(), pg);
+ reader.read(book.getMeta().getLuid(), pg);
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
book.setCached(true);
}
setEnabled(false);
new Thread(new Runnable() {
+ @Override
public void run() {
run.run();
refreshBooks();
* @param onSuccess
* Action to execute on success
*/
- private void imprt(final String url, final Runnable onSuccess,
+ private void imprt(final String url, final StoryRunnable onSuccess,
String onSuccessPgName) {
final Progress pg = new Progress();
final Progress pgImprt = new Progress();
pg.addProgress(pgOnSuccess, 5);
outOfUi(pg, new Runnable() {
+ @Override
public void run() {
Exception ex = null;
+ Story story = null;
try {
- Instance.getLibrary().imprt(BasicReader.getUrl(url),
+ story = reader.getLibrary().imprt(BasicReader.getUrl(url),
pgImprt);
} catch (IOException e) {
ex = e;
if (!ok) {
Instance.syserr(e);
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
JOptionPane.showMessageDialog(GuiReaderFrame.this,
"Cannot import: " + url, e.getMessage(),
});
} else {
if (onSuccess != null) {
- onSuccess.run();
+ onSuccess.run(story);
}
}
pgOnSuccess.done();