try {
Reader reader = BasicReader.getReader();
if (library) {
- reader.setStory(story, null);
+ reader.setMeta(story);
} else {
- reader.setStory(BasicReader.getUrl(story), null);
+ reader.setMeta(BasicReader.getUrl(story), null);
}
if (chapString != null) {
try {
- reader.read(Integer.parseInt(chapString));
+ reader.setChapter(Integer.parseInt(chapString));
+ reader.read();
} catch (NumberFormatException e) {
Instance.syserr(new IOException(
"Chapter number cannot be parsed: " + chapString, e));
* which to retrieve stories, then process them into <tt>epub</tt> (or other)
* files that you can read anywhere.
* <p>
- * It has support for a {@link be.nikiroo.fanfix.BasicLibrary} system, too.
+ * It has support for a {@link be.nikiroo.fanfix.library.BasicLibrary} system,
+ * too.
*
* @author niki
*/
private static ReaderType defaultType = ReaderType.GUI;
private BasicLibrary lib;
+ private MetaData meta;
private Story story;
+ private int chapter;
/**
* Take the default reader type configuration from the config file.
}
}
- public Story getStory() {
+ public synchronized Story getStory(Progress pg) {
+ if (story == null) {
+ story = getLibrary().getStory(meta.getLuid(), pg);
+ }
+
return story;
}
return lib;
}
- public void setLibrary(LocalLibrary lib) {
+ public void setLibrary(BasicLibrary lib) {
this.lib = lib;
}
- public void setStory(String luid, Progress pg) throws IOException {
- story = getLibrary().getStory(luid, pg);
- if (story == null) {
+ public MetaData getMeta() {
+ return meta;
+ }
+
+ public synchronized void setMeta(MetaData meta) throws IOException {
+ setMeta(meta == null ? null : meta.getLuid()); // must check the library
+ }
+
+ public synchronized void setMeta(String luid) throws IOException {
+ story = null;
+ meta = getLibrary().getInfo(luid);
+
+ if (meta == null) {
throw new IOException("Cannot retrieve story from library: " + luid);
}
}
- public void setStory(URL source, Progress pg) throws IOException {
+ public synchronized void setMeta(URL source, Progress pg)
+ throws IOException {
BasicSupport support = BasicSupport.getSupport(source);
if (support == null) {
throw new IOException("URL not supported: " + source.toString());
throw new IOException(
"Cannot retrieve story from external source: "
+ source.toString());
-
}
+
+ meta = story.getMeta();
+ }
+
+ public int getChapter() {
+ return chapter;
}
- public void read() throws IOException {
- read(-1);
+ public void setChapter(int chapter) {
+ this.chapter = chapter;
}
/**
}
/**
- * The default {@link ReaderType} used when calling
+ * The default {@link Reader.ReaderType} used when calling
* {@link BasicReader#getReader()}.
*
* @return the default type
}
/**
- * The default {@link ReaderType} used when calling
+ * The default {@link Reader.ReaderType} used when calling
* {@link BasicReader#getReader()}.
*
* @param defaultType
*/
class CliReader extends BasicReader {
public void read() throws IOException {
- if (getStory() == null) {
+ MetaData meta = getMeta();
+
+ if (meta == null) {
throw new IOException("No story to read");
}
String title = "";
String author = "";
- MetaData meta = getStory().getMeta();
- if (meta != null) {
- if (meta.getTitle() != null) {
- title = meta.getTitle();
- }
+ if (meta.getTitle() != null) {
+ title = meta.getTitle();
+ }
- if (meta.getAuthor() != null) {
- author = "©" + meta.getAuthor();
- if (meta.getDate() != null && !meta.getDate().isEmpty()) {
- author = author + " (" + meta.getDate() + ")";
- }
+ if (meta.getAuthor() != null) {
+ author = "©" + meta.getAuthor();
+ if (meta.getDate() != null && !meta.getDate().isEmpty()) {
+ author = author + " (" + meta.getDate() + ")";
}
}
System.out.println(author);
System.out.println("");
- for (Chapter chap : getStory()) {
+ // TODO: progress?
+ for (Chapter chap : getStory(null)) {
if (chap.getName() != null && !chap.getName().isEmpty()) {
System.out.println(Instance.getTrans().getString(
StringId.CHAPTER_NAMED, chap.getNumber(),
}
public void read(int chapter) throws IOException {
- if (getStory() == null) {
+ MetaData meta = getMeta();
+
+ if (meta == null) {
throw new IOException("No story to read");
}
- if (chapter > getStory().getChapters().size()) {
+ // TODO: progress?
+ if (chapter > getStory(null).getChapters().size()) {
System.err.println("Chapter " + chapter + ": no such chapter");
} else {
- Chapter chap = getStory().getChapters().get(chapter - 1);
+ Chapter chap = getStory(null).getChapters().get(chapter - 1);
System.out.println("Chapter " + chap.getNumber() + ": "
+ chap.getName());
import be.nikiroo.fanfix.Instance;
import be.nikiroo.fanfix.VersionCheck;
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;
}
public void read() throws IOException {
- if (getStory() == null) {
+ MetaData meta = getMeta();
+
+ if (meta == null) {
throw new IOException("No story to read");
}
- open(getStory().getMeta().getLuid(), null);
- }
-
- public void read(int chapter) throws IOException {
- // TODO: show a special page?
- read();
+ read(meta.getLuid(), null);
}
/**
}
// open the given book
- void open(String luid, Progress pg) throws IOException {
+ void read(String luid, Progress pg) throws IOException {
File file = localLibrary.getFile(luid);
if (file == null) {
imprt(luid, pg);
file = localLibrary.getFile(luid);
}
+ // TODO: show a special page for the chapter?
openExternal(getLibrary().getInfo(luid), file);
}
- void changeType(String luid, String newType) {
+ void changeType(String luid, String newSource) {
try {
- localLibrary.changeSource(luid, newType, null);
- getLibrary().changeSource(luid, newType, null);
+ localLibrary.changeSource(luid, newSource, null);
+ getLibrary().changeSource(luid, newSource, null);
} catch (IOException e) {
Instance.syserr(e);
}
outOfUi(pg, new Runnable() {
public void run() {
try {
- reader.open(book.getMeta().getLuid(), pg);
+ reader.read(book.getMeta().getLuid(), pg);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
book.setCached(true);
import java.io.IOException;
import java.net.URL;
+import be.nikiroo.fanfix.data.MetaData;
import be.nikiroo.fanfix.data.Story;
import be.nikiroo.fanfix.library.BasicLibrary;
-import be.nikiroo.fanfix.library.LocalLibrary;
import be.nikiroo.utils.Progress;
+/**
+ * A {@link Reader} is a class that will handle {@link Story} reading and
+ * browsing.
+ *
+ * @author niki
+ */
public interface Reader {
/**
* A type of {@link BasicReader}.
};
/**
- * Return the current {@link Story}.
+ * Return the current target {@link MetaData}.
+ *
+ * @return the meta
+ */
+ public MetaData getMeta();
+
+ /**
+ * Return the current {@link Story} as described by the current
+ * {@link MetaData}.
+ *
+ * @param pg
+ * the optional progress
*
* @return the {@link Story}
*/
- public Story getStory();
+ public Story getStory(Progress pg);
/**
- * The {@link LocalLibrary} to load the stories from (by default, takes the
- * default {@link LocalLibrary}).
+ * The {@link BasicLibrary} to load the stories from (by default, takes the
+ * default {@link BasicLibrary}).
*
- * @return the {@link LocalLibrary}
+ * @return the {@link BasicLibrary}
*/
public BasicLibrary getLibrary();
/**
- * Change the {@link LocalLibrary} that will be managed by this
+ * Change the {@link BasicLibrary} that will be managed by this
* {@link BasicReader}.
*
* @param lib
- * the new {@link LocalLibrary}
+ * the new {@link BasicLibrary}
*/
- public void setLibrary(LocalLibrary lib);
+ public void setLibrary(BasicLibrary lib);
/**
- * Set a {@link Story} from the current {@link Library} into the
+ * Set a {@link Story} from the current {@link BasicLibrary} into the
* {@link Reader}.
*
* @param luid
* the {@link Story} ID
- * @param pg
- * the optional progress reporter
*
* @throws IOException
* in case of I/O error
*/
- public void setStory(String luid, Progress pg) throws IOException;
+ public void setMeta(String luid) throws IOException;
+
+ /**
+ * Set a {@link Story} from the current {@link BasicLibrary} into the
+ * {@link Reader}.
+ *
+ * @param meta
+ * the meta
+ *
+ * @throws IOException
+ * in case of I/O error
+ */
+ public void setMeta(MetaData meta) throws IOException;
/**
* Set an external {@link Story} into this {@link Reader}.
* @throws IOException
* in case of I/O error
*/
- public void setStory(URL source, Progress pg) throws IOException;
+ public void setMeta(URL source, Progress pg) throws IOException;
/**
* Start the {@link Story} Reading.
public void read() throws IOException;
/**
- * Read the selected chapter (starting at 1, 0 = description, -1 = none).
+ * The selected chapter to start reading at (starting at 1, 0 = description,
+ * -1 = none).
+ *
+ * @return the chapter, or -1 for "no chapter"
+ */
+ public int getChapter();
+
+ /**
+ * The selected chapter to start reading at (starting at 1, 0 = description,
+ * -1 = none).
*
* @param chapter
* the chapter, or -1 for "no chapter"
- *
- * @throws IOException
- * in case of I/O error or if the {@link Story} was not
- * previously set
*/
- public void read(int chapter) throws IOException;
+ public void setChapter(int chapter);
/**
* Start the reader in browse mode for the given source (or pass NULL for
return backendType;
}
- public void read(int chapter) throws IOException {
- if (getStory() == null) {
- throw new IOException("No story to read");
- }
-
- start(getStory().getMeta(), chapter);
- }
-
- public void browse(String source) {
- start(getLibrary().getListBySource(source));
- }
-
- /**
- * Start the application with the given stories.
- *
- * @param metas
- * the stories to display
- */
- private void start(List<MetaData> metas) {
+ public void read() throws IOException {
try {
- TuiReaderApplication app = new TuiReaderApplication(metas, this,
+ TuiReaderApplication app = new TuiReaderApplication(this,
guessBackendType());
new Thread(app).start();
} catch (Exception e) {
}
}
- /**
- * Start the application with the given {@link MetaData} at the given open
- * chapter.
- *
- * @param meta
- * the story to display
- * @param chapter
- * the chapter to open
- */
- private void start(MetaData meta, int chapter) {
+ public void browse(String source) {
+ List<MetaData> metas = getLibrary().getListBySource(source);
try {
- TuiReaderApplication app = new TuiReaderApplication(meta, chapter,
- this, guessBackendType());
+ TuiReaderApplication app = new TuiReaderApplication(metas, this,
+ guessBackendType());
new Thread(app).start();
} catch (Exception e) {
Instance.syserr(e);
import be.nikiroo.fanfix.data.MetaData;
import be.nikiroo.fanfix.data.Story;
import be.nikiroo.fanfix.library.BasicLibrary;
-import be.nikiroo.fanfix.library.LocalLibrary;
import be.nikiroo.utils.Progress;
/**
- * Manages the TUI reader, links and manages the {@link TWindow}s, starts the
- * correct output mode.
+ * Manages the TUI general mode and links and manages the {@link TWindow}s.
+ * <p>
+ * It will also enclose a {@link Reader} and simply handle the reading part
+ * differently (it will create the required sub-windows and display them).
*
* @author niki
*/
class TuiReaderApplication extends TApplication implements Reader {
private Reader reader;
- public TuiReaderApplication(MetaData meta, int chapter, Reader reader,
- BackendType backend) throws Exception {
- this(reader, backend);
+ // start reading if meta present
+ public TuiReaderApplication(Reader reader, BackendType backend)
+ throws Exception {
+ super(backend);
+ init(reader);
- new TuiReaderMainWindow(this, meta, chapter);
- }
+ MetaData meta = getMeta();
- public TuiReaderApplication(List<MetaData> stories, Reader reader,
- TApplication.BackendType backend) throws Exception {
- this(reader, backend);
+ new TuiReaderMainWindow(this).setMeta(meta);
- new TuiReaderMainWindow(this, stories);
+ if (meta != null) {
+ read();
+ }
}
- private TuiReaderApplication(Reader reader, TApplication.BackendType backend)
- throws Exception {
+ public TuiReaderApplication(List<MetaData> stories, Reader reader,
+ TApplication.BackendType backend) throws Exception {
super(backend);
+ init(reader);
- this.reader = reader;
-
- // Add the menus
- addFileMenu();
- addEditMenu();
- addWindowMenu();
- addHelpMenu();
-
- getBackend().setTitle("Fanfix");
+ new TuiReaderMainWindow(this).setMetas(stories);
}
public void read() throws IOException {
- reader.read();
- }
-
- public void read(int chapter) throws IOException {
- reader.read(chapter);
- }
+ MetaData meta = getMeta();
- public void open(MetaData meta) {
- open(meta, -1);
- }
+ if (meta == null) {
+ throw new IOException("No story to read");
+ }
- public void open(MetaData meta, int chapter) {
// TODO: open in editor + external option
if (!meta.isImageDocument()) {
- new TuiReaderStoryWindow(this, getLibrary(), meta, chapter);
+ new TuiReaderStoryWindow(this, getLibrary(), meta, getChapter());
} else {
try {
BasicReader.openExternal(getLibrary(), meta.getLuid());
}
}
- public Story getStory() {
- return reader.getStory();
+ public MetaData getMeta() {
+ return reader.getMeta();
+ }
+
+ public Story getStory(Progress pg) {
+ return reader.getStory(pg);
}
public BasicLibrary getLibrary() {
return reader.getLibrary();
}
- public void setLibrary(LocalLibrary lib) {
+ public void setLibrary(BasicLibrary lib) {
reader.setLibrary(lib);
}
- public void setStory(String luid, Progress pg) throws IOException {
- reader.setStory(luid, pg);
+ public void setMeta(MetaData meta) throws IOException {
+ reader.setMeta(meta);
+ }
+
+ public void setMeta(String luid) throws IOException {
+ reader.setMeta(luid);
}
- public void setStory(URL source, Progress pg) throws IOException {
- reader.setStory(source, pg);
+ public void setMeta(URL source, Progress pg) throws IOException {
+ reader.setMeta(source, pg);
}
public void browse(String source) {
reader.browse(source);
}
+
+ public int getChapter() {
+ return reader.getChapter();
+ }
+
+ public void setChapter(int chapter) {
+ reader.setChapter(chapter);
+ }
+
+ private void init(Reader reader) {
+ this.reader = reader;
+
+ // Add the menus
+ addFileMenu();
+ addEditMenu();
+ addWindowMenu();
+ addHelpMenu();
+
+ getBackend().setTitle("Fanfix");
+ }
}
package be.nikiroo.fanfix.reader;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import jexer.TCommand;
import jexer.TKeypress;
import jexer.TList;
-import jexer.TRadioGroup;
-import jexer.TTreeItem;
-import jexer.TTreeView;
import jexer.TWindow;
+import be.nikiroo.fanfix.Instance;
import be.nikiroo.fanfix.data.MetaData;
+import be.nikiroo.fanfix.library.BasicLibrary;
/**
* The library window, that will list all the (filtered) stories available in
- * this {@link Library}.
+ * this {@link BasicLibrary}.
*
* @author niki
*/
private TList list;
private List<MetaData> listKeys;
private List<String> listItems;
- private TuiReaderApplication reader;
+ private Reader reader;
/**
- * Create a new {@link TuiReaderMainWindow} with the given stories in the
+ * Create a new {@link TuiReaderMainWindow} with the given story in the
* list.
*
* @param reader
* the reader and main application
- * @param metas
- * the stories to display
- */
- public TuiReaderMainWindow(TuiReaderApplication reader, List<MetaData> metas) {
- this(reader);
- setMetas(metas);
- }
-
- /**
- * Create a new {@link TuiReaderMainWindow} with only the given
- * {@link MetaData} in the list, and open this {@link MetaData} at the given
- * chapter.
- *
- * @param reader
- * the reader and main application
* @param meta
* the story to display
- * @param chapter
- * the chapter to open
*/
- public TuiReaderMainWindow(TuiReaderApplication reader, MetaData meta,
- int chapter) {
+ public TuiReaderMainWindow(TuiReaderApplication reader, MetaData meta) {
this(reader);
List<MetaData> metas = new ArrayList<MetaData>();
metas.add(meta);
setMetas(metas);
-
- reader.open(meta, chapter);
}
/**
*/
public TuiReaderMainWindow(TuiReaderApplication reader) {
// Construct a demo window. X and Y don't matter because it will be
- // centered on screen.
+ // centred on screen.
super(reader, "Library", 0, 0, 60, 18, CENTERED | RESIZABLE
| UNCLOSABLE);
statusBar = newStatusBar("Library");
statusBar.addShortcutKeypress(TKeypress.kbF10, TCommand.cmExit, "Exit");
- if (false) {
- addLabel("Label (1,1)", 1, 1);
- addButton("&Button (35,1)", 35, 1, new TAction() {
- public void DO() {
- }
- });
- addCheckbox(1, 2, "Checky (1,2)", false);
- addProgressBar(1, 3, 30, 42);
- TRadioGroup groupy = addRadioGroup(1, 4, "Radio groupy");
- groupy.addRadioButton("Fanfan");
- groupy.addRadioButton("Tulipe");
- addField(1, 10, 20, false, "text not fixed.");
- addField(1, 11, 20, true, "text fixed.");
- addText("20x4 Text in (12,20)", 1, 12, 20, 4);
-
- TTreeView tree = addTreeView(30, 5, 20, 5);
- TTreeItem root = new TTreeItem(tree, "expended root", true);
- tree.setSelected(root); // needed to allow arrow navigation without
- // mouse-clicking before
-
- root.addChild("child");
- root.addChild("child 2").addChild("sub child");
+ // TODO: remove when not used anymore
+
+ // addLabel("Label (1,1)", 1, 1);
+ // addButton("&Button (35,1)", 35, 1, new TAction() {
+ // public void DO() {
+ // }
+ // });
+ // addCheckbox(1, 2, "Checky (1,2)", false);
+ // addProgressBar(1, 3, 30, 42);
+ // TRadioGroup groupy = addRadioGroup(1, 4, "Radio groupy");
+ // groupy.addRadioButton("Fanfan");
+ // groupy.addRadioButton("Tulipe");
+ // addField(1, 10, 20, false, "text not fixed.");
+ // addField(1, 11, 20, true, "text fixed.");
+ // addText("20x4 Text in (12,20)", 1, 12, 20, 4);
+ //
+ // TTreeView tree = addTreeView(30, 5, 20, 5);
+ // TTreeItem root = new TTreeItem(tree, "expended root", true);
+ // tree.setSelected(root); // needed to allow arrow navigation without
+ // // mouse-clicking before
+ //
+ // root.addChild("child");
+ // root.addChild("child 2").addChild("sub child");
+ }
+ /**
+ * Update the list of stories displayed in this {@link TWindow}.
+ *
+ * @param meta
+ * the new (unique) story to display
+ */
+ public void setMeta(MetaData meta) {
+ List<MetaData> metas = new ArrayList<MetaData>();
+ if (meta != null) {
+ metas.add(meta);
}
+
+ setMetas(metas);
}
/**
}
private void enterOnStory(MetaData meta) {
- reader.open(meta);
+ try {
+ reader.setChapter(-1);
+ reader.setMeta(meta);
+ reader.read();
+ } catch (IOException e) {
+ Instance.syserr(e);
+ }
}
private String desc(MetaData meta) {
private MetaData meta;
private Story story;
private TText textField;
- private int chapter = -2;
+ private int chapter = -1;
private List<TButton> navigationButtons;
private TLabel chapterName;