From: Niki Roo Date: Wed, 5 Jul 2017 17:20:10 +0000 (+0200) Subject: Code cleanup 2 (a third one is pending) X-Git-Tag: fanfix-1.6.0~19 X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=commitdiff_plain;h=6322ab64949f9f4ae2b04b9504d58a301039d670 Code cleanup 2 (a third one is pending) --- diff --git a/README.md b/README.md index 98a0c9b..22a5dc2 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ Currently missing, but either in progress or planned: - [ ] Real menus - [x] Open a story in the reader and/or natively - [ ] Update the screenshots + - [ ] Remember the current chapter and current read status of stories - [ ] Network support - [x] A server that can send the stories - [x] A network implementation of the Library diff --git a/src/be/nikiroo/fanfix/reader/BasicReader.java b/src/be/nikiroo/fanfix/reader/BasicReader.java index cbd4e03..2c04006 100644 --- a/src/be/nikiroo/fanfix/reader/BasicReader.java +++ b/src/be/nikiroo/fanfix/reader/BasicReader.java @@ -63,7 +63,7 @@ public abstract class BasicReader implements Reader { } public void setStory(String luid, Progress pg) throws IOException { - story = lib.getStory(luid, pg); + story = getLibrary().getStory(luid, pg); if (story == null) { throw new IOException("Cannot retrieve story from library: " + luid); } @@ -84,6 +84,10 @@ public abstract class BasicReader implements Reader { } } + public void read() throws IOException { + read(-1); + } + /** * Return a new {@link BasicReader} ready for use if one is configured. *

@@ -177,11 +181,12 @@ public abstract class BasicReader implements Reader { * @throws IOException * in case of I/O error */ - public static void open(BasicLibrary lib, String luid) throws IOException { + public static void openExternal(BasicLibrary lib, String luid) + throws IOException { MetaData meta = lib.getInfo(luid); File target = lib.getFile(luid); - open(meta, target); + openExternal(meta, target); } /** @@ -196,7 +201,8 @@ public abstract class BasicReader implements Reader { * @throws IOException * in case of I/O error */ - protected static void open(MetaData meta, File target) throws IOException { + protected static void openExternal(MetaData meta, File target) + throws IOException { String program = null; if (meta.isImageDocument()) { program = Instance.getUiConfig().getString( diff --git a/src/be/nikiroo/fanfix/reader/GuiReader.java b/src/be/nikiroo/fanfix/reader/GuiReader.java index 06b3473..2c30ab6 100644 --- a/src/be/nikiroo/fanfix/reader/GuiReader.java +++ b/src/be/nikiroo/fanfix/reader/GuiReader.java @@ -218,7 +218,7 @@ class GuiReader extends BasicReader { file = localLibrary.getFile(luid); } - open(getLibrary().getInfo(luid), file); + openExternal(getLibrary().getInfo(luid), file); } void changeType(String luid, String newType) { diff --git a/src/be/nikiroo/fanfix/reader/Reader.java b/src/be/nikiroo/fanfix/reader/Reader.java index d728578..09d45c1 100644 --- a/src/be/nikiroo/fanfix/reader/Reader.java +++ b/src/be/nikiroo/fanfix/reader/Reader.java @@ -70,8 +70,8 @@ public interface Reader { public void setLibrary(LocalLibrary lib); /** - * Create a new {@link BasicReader} for a {@link Story} in the - * {@link LocalLibrary}. + * Set a {@link Story} from the current {@link Library} into the + * {@link Reader}. * * @param luid * the {@link Story} ID @@ -84,7 +84,7 @@ public interface Reader { public void setStory(String luid, Progress pg) throws IOException; /** - * Create a new {@link BasicReader} for an external {@link Story}. + * Set an external {@link Story} into this {@link Reader}. * * @param source * the {@link Story} {@link URL} @@ -106,10 +106,10 @@ public interface Reader { public void read() throws IOException; /** - * Read the selected chapter (starting at 1). + * Read the selected chapter (starting at 1, 0 = description, -1 = none). * * @param chapter - * the chapter + * the chapter, or -1 for "no chapter" * * @throws IOException * in case of I/O error or if the {@link Story} was not @@ -126,5 +126,4 @@ public interface Reader { * all */ public void browse(String source); - } diff --git a/src/be/nikiroo/fanfix/reader/TuiReader.java b/src/be/nikiroo/fanfix/reader/TuiReader.java index e9f909d..91b6268 100644 --- a/src/be/nikiroo/fanfix/reader/TuiReader.java +++ b/src/be/nikiroo/fanfix/reader/TuiReader.java @@ -1,27 +1,95 @@ package be.nikiroo.fanfix.reader; import java.io.IOException; +import java.util.List; +import jexer.TApplication; +import jexer.TApplication.BackendType; import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.data.MetaData; +/** + * This {@link Reader}is based upon the TUI widget library 'jexer' + * (https://github.com/klamonte/jexer/) and offer, as its name suggest, a Text + * User Interface. + *

+ * It is expected to be on par with the GUI version. + * + * @author niki + */ class TuiReader extends BasicReader { - public void read() throws IOException { - if (getStory() == null) { - throw new IOException("No story to read"); + /** + * Will detect the backend to use. + *

+ * Swing is the default backend on Windows and MacOS while evreything else + * will use XTERM unless explicitly overridden by jexer.Swing = + * true or false. + * + * @return the backend to use + */ + private static BackendType guessBackendType() { + // TODO: allow a config option to force one or the other? + TApplication.BackendType backendType = TApplication.BackendType.XTERM; + if (System.getProperty("os.name").startsWith("Windows")) { + backendType = TApplication.BackendType.SWING; + } + + if (System.getProperty("os.name").startsWith("Mac")) { + backendType = TApplication.BackendType.SWING; + } + + if (System.getProperty("jexer.Swing") != null) { + if (System.getProperty("jexer.Swing", "false").equals("true")) { + backendType = TApplication.BackendType.SWING; + } else { + backendType = TApplication.BackendType.XTERM; + } } - open(getLibrary(), getStory().getMeta().getLuid()); + return backendType; } public void read(int chapter) throws IOException { - // TODO: show a special page? - read(); + 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 metas) { + try { + TuiReaderApplication app = new TuiReaderApplication(metas, this, + guessBackendType()); + new Thread(app).start(); + } catch (Exception e) { + Instance.syserr(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) { try { - TuiReaderApplication app = new TuiReaderApplication(getLibrary() - .getListBySource(source), this); + TuiReaderApplication app = new TuiReaderApplication(meta, chapter, + this, guessBackendType()); new Thread(app).start(); } catch (Exception e) { Instance.syserr(e); diff --git a/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java b/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java index 719f095..b7f8308 100644 --- a/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java +++ b/src/be/nikiroo/fanfix/reader/TuiReaderApplication.java @@ -1,42 +1,43 @@ package be.nikiroo.fanfix.reader; import java.io.IOException; +import java.net.URL; import java.util.List; import jexer.TApplication; import jexer.TMessageBox; +import jexer.TWindow; 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; -class TuiReaderApplication extends TApplication { - private BasicReader reader; +/** + * Manages the TUI reader, links and manages the {@link TWindow}s, starts the + * correct output mode. + * + * @author niki + */ +class TuiReaderApplication extends TApplication implements Reader { + private Reader reader; - private static BackendType guessBackendType() { - // Swing is the default backend on Windows unless explicitly - // overridden by jexer.Swing. - TApplication.BackendType backendType = TApplication.BackendType.XTERM; - if (System.getProperty("os.name").startsWith("Windows")) { - backendType = TApplication.BackendType.SWING; - } - if (System.getProperty("os.name").startsWith("Mac")) { - backendType = TApplication.BackendType.SWING; - } - if (System.getProperty("jexer.Swing") != null) { - if (System.getProperty("jexer.Swing", "false").equals("true")) { - backendType = TApplication.BackendType.SWING; - } else { - backendType = TApplication.BackendType.XTERM; - } - } - return backendType; - } + public TuiReaderApplication(MetaData meta, int chapter, Reader reader, + BackendType backend) throws Exception { + this(reader, backend); - public TuiReaderApplication(List stories, BasicReader reader) - throws Exception { - this(stories, reader, guessBackendType()); + new TuiReaderMainWindow(this, meta, chapter); } - public TuiReaderApplication(List stories, BasicReader reader, + public TuiReaderApplication(List stories, Reader reader, TApplication.BackendType backend) throws Exception { + this(reader, backend); + + new TuiReaderMainWindow(this, stories); + } + + private TuiReaderApplication(Reader reader, TApplication.BackendType backend) + throws Exception { super(backend); this.reader = reader; @@ -48,21 +49,55 @@ class TuiReaderApplication extends TApplication { addHelpMenu(); getBackend().setTitle("Fanfix"); + } - new TuiReaderMainWindow(this, stories); + public void read() throws IOException { + reader.read(); + } + + public void read(int chapter) throws IOException { + reader.read(chapter); } public void open(MetaData meta) { + open(meta, -1); + } + + public void open(MetaData meta, int chapter) { // TODO: open in editor + external option if (!meta.isImageDocument()) { - new TuiReaderStoryWindow(this, reader.getLibrary(), meta); + new TuiReaderStoryWindow(this, getLibrary(), meta, chapter); } else { try { - BasicReader.open(reader.getLibrary(), meta.getLuid()); + BasicReader.openExternal(getLibrary(), meta.getLuid()); } catch (IOException e) { messageBox("Error when trying to open the story", e.getMessage(), TMessageBox.Type.OK); } } } + + public Story getStory() { + return reader.getStory(); + } + + public BasicLibrary getLibrary() { + return reader.getLibrary(); + } + + public void setLibrary(LocalLibrary lib) { + reader.setLibrary(lib); + } + + public void setStory(String luid, Progress pg) throws IOException { + reader.setStory(luid, pg); + } + + public void setStory(URL source, Progress pg) throws IOException { + reader.setStory(source, pg); + } + + public void browse(String source) { + reader.browse(source); + } } diff --git a/src/be/nikiroo/fanfix/reader/TuiReaderMainWindow.java b/src/be/nikiroo/fanfix/reader/TuiReaderMainWindow.java index 8f00b49..3b5dc5d 100644 --- a/src/be/nikiroo/fanfix/reader/TuiReaderMainWindow.java +++ b/src/be/nikiroo/fanfix/reader/TuiReaderMainWindow.java @@ -13,6 +13,12 @@ import jexer.TTreeView; import jexer.TWindow; import be.nikiroo.fanfix.data.MetaData; +/** + * The library window, that will list all the (filtered) stories available in + * this {@link Library}. + * + * @author niki + */ class TuiReaderMainWindow extends TWindow { private TList list; private List listKeys; @@ -20,15 +26,49 @@ class TuiReaderMainWindow extends TWindow { private TuiReaderApplication reader; /** - * Constructor. + * Create a new {@link TuiReaderMainWindow} with the given stories in the + * list. * * @param reader * the reader and main application - * @param stories + * @param metas * the stories to display */ - public TuiReaderMainWindow(TuiReaderApplication reader, - List stories) { + public TuiReaderMainWindow(TuiReaderApplication reader, List 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) { + this(reader); + + List metas = new ArrayList(); + metas.add(meta); + setMetas(metas); + + reader.open(meta, chapter); + } + + /** + * Create a new {@link TuiReaderMainWindow} without any stories in the list. + * + * @param reader + * the reader and main application + */ + public TuiReaderMainWindow(TuiReaderApplication reader) { // Construct a demo window. X and Y don't matter because it will be // centered on screen. super(reader, "Library", 0, 0, 60, 18, CENTERED | RESIZABLE @@ -40,14 +80,6 @@ class TuiReaderMainWindow extends TWindow { listKeys = new ArrayList(); listItems = new ArrayList(); - - if (stories != null) { - for (MetaData meta : stories) { - listKeys.add(meta); - listItems.add(desc(meta)); - } - } - list = addList(listItems, 0, 0, getWidth(), getHeight(), new TAction() { @Override public void DO() { @@ -57,7 +89,7 @@ class TuiReaderMainWindow extends TWindow { } }); - // TODO: add the current "type" or filter + // TODO: add the current "source/type" or filter statusBar = newStatusBar("Library"); statusBar.addShortcutKeypress(TKeypress.kbF10, TCommand.cmExit, "Exit"); @@ -87,6 +119,26 @@ class TuiReaderMainWindow extends TWindow { } } + /** + * Update the list of stories displayed in this {@link TWindow}. + * + * @param metas + * the new list of stories to display + */ + public void setMetas(List metas) { + listKeys.clear(); + listItems.clear(); + + if (metas != null) { + for (MetaData meta : metas) { + listKeys.add(meta); + listItems.add(desc(meta)); + } + } + + list.setList(listItems); + } + private void enterOnStory(MetaData meta) { reader.open(meta); } diff --git a/src/be/nikiroo/fanfix/reader/TuiReaderStoryWindow.java b/src/be/nikiroo/fanfix/reader/TuiReaderStoryWindow.java index 71b5b5e..0f6af07 100644 --- a/src/be/nikiroo/fanfix/reader/TuiReaderStoryWindow.java +++ b/src/be/nikiroo/fanfix/reader/TuiReaderStoryWindow.java @@ -27,11 +27,7 @@ class TuiReaderStoryWindow extends TWindow { private List navigationButtons; private TLabel chapterName; - public TuiReaderStoryWindow(TApplication app, BasicLibrary lib, - MetaData meta) { - this(app, lib, meta, 0); - } - + // chapter: -1 for "none" (0 is desc) public TuiReaderStoryWindow(TApplication app, BasicLibrary lib, MetaData meta, int chapter) { super(app, desc(meta), 0, 0, 60, 18, CENTERED | RESIZABLE);