Instance: use getInstance()
[nikiroo-utils.git] / src / be / nikiroo / fanfix / reader / tui / TuiReaderMainWindow.java
index 1fa6d8b6e19a42b0752b8afe05c4626c89507fba..b1ebcc2e6971de4c25e119c5e6fbbb7a32043844 100644 (file)
@@ -5,17 +5,24 @@ import java.util.ArrayList;
 import java.util.List;
 
 import jexer.TAction;
+import jexer.TComboBox;
 import jexer.TCommand;
+import jexer.TField;
 import jexer.TFileOpenBox.Type;
 import jexer.TKeypress;
+import jexer.TLabel;
 import jexer.TList;
+import jexer.TStatusBar;
 import jexer.TWindow;
+import jexer.event.TCommandEvent;
+import jexer.event.TKeypressEvent;
 import jexer.event.TMenuEvent;
+import jexer.event.TResizeEvent;
 import be.nikiroo.fanfix.Instance;
 import be.nikiroo.fanfix.data.MetaData;
 import be.nikiroo.fanfix.library.BasicLibrary;
 import be.nikiroo.fanfix.output.BasicOutput.OutputType;
-import be.nikiroo.fanfix.reader.Reader;
+import be.nikiroo.jexer.TSizeConstraint;
 
 /**
  * The library window, that will list all the (filtered) stories available in
@@ -24,11 +31,28 @@ import be.nikiroo.fanfix.reader.Reader;
  * @author niki
  */
 class TuiReaderMainWindow extends TWindow {
+       public static final int MENU_SEARCH = 1100;
+       public static final TCommand CMD_SEARCH = new TCommand(MENU_SEARCH) {
+       };
+
+       public enum Mode {
+               SOURCE, AUTHOR,
+       }
+
        private TList list;
        private List<MetaData> listKeys;
        private List<String> listItems;
-       private Reader reader;
-       private String source;
+       private TuiReaderApplication reader;
+
+       private Mode mode = Mode.SOURCE;
+       private String target = null;
+       private String filter = "";
+
+       private List<TSizeConstraint> sizeConstraints = new ArrayList<TSizeConstraint>();
+
+       // The 2 comboboxes used to select by source/author
+       private TComboBox selectTargetBox;
+       private TComboBox selectBox;
 
        /**
         * Create a new {@link TuiReaderMainWindow} without any stories in the list.
@@ -43,23 +67,17 @@ class TuiReaderMainWindow extends TWindow {
 
                this.reader = reader;
 
-               maximize();
-
                listKeys = new ArrayList<MetaData>();
                listItems = new ArrayList<String>();
-               list = addList(listItems, 0, 0, getWidth(), getHeight(), new TAction() {
-                       @Override
-                       public void DO() {
-                               MetaData meta = getSelectedMeta();
-                               if (meta != null) {
-                                       readStory(meta);
-                               }
-                       }
-               });
 
-               // TODO: add the current "source/type" or filter
-               statusBar = newStatusBar("Library");
-               statusBar.addShortcutKeypress(TKeypress.kbF10, TCommand.cmExit, "Exit");
+               addList();
+               addSearch();
+               addSelect();
+
+               TStatusBar statusBar = reader.setStatusBar(this, "Library");
+               statusBar.addShortcutKeypress(TKeypress.kbCtrlF, CMD_SEARCH, "Search");
+
+               TSizeConstraint.resize(sizeConstraints);
 
                // TODO: remove when not used anymore
 
@@ -86,6 +104,129 @@ class TuiReaderMainWindow extends TWindow {
                // root.addChild("child 2").addChild("sub child");
        }
 
+       private void addSearch() {
+               TLabel lblSearch = addLabel("Search: ", 0, 0);
+
+               TField search = new TField(this, 0, 0, 1, true) {
+                       @Override
+                       public void onKeypress(TKeypressEvent keypress) {
+                               super.onKeypress(keypress);
+                               TKeypress key = keypress.getKey();
+                               if (key.isFnKey() && key.getKeyCode() == TKeypress.ENTER) {
+                                       TuiReaderMainWindow.this.filter = getText();
+                                       TuiReaderMainWindow.this.refreshStories();
+                               }
+                       }
+               };
+
+               TSizeConstraint.setSize(sizeConstraints, lblSearch, 5, 1, null, null);
+               TSizeConstraint.setSize(sizeConstraints, search, 15, 1, -5, null);
+       }
+
+       private void addList() {
+               list = addList(listItems, 0, 0, 10, 10, new TAction() {
+                       @Override
+                       public void DO() {
+                               MetaData meta = getSelectedMeta();
+                               if (meta != null) {
+                                       readStory(meta);
+                               }
+                       }
+               });
+
+               TSizeConstraint.setSize(sizeConstraints, list, 0, 7, 0, 0);
+       }
+
+       private void addSelect() {
+               // TODO: i18n
+               final List<String> selects = new ArrayList<String>();
+               selects.add("(show all)");
+               selects.add("Sources");
+               selects.add("Author");
+
+               final List<String> selectTargets = new ArrayList<String>();
+               selectTargets.add("");
+
+               TLabel lblSelect = addLabel("Select: ", 0, 0);
+
+               TAction onSelect = new TAction() {
+                       @Override
+                       public void DO() {
+                               String smode = selectBox.getText();
+                               boolean showTarget;
+                               if (smode == null || smode.equals("(show all)")) {
+                                       showTarget = false;
+                               } else if (smode.equals("Sources")) {
+                                       selectTargets.clear();
+                                       selectTargets.add("(show all)");
+                                       try {
+                                               for (String source : reader.getLibrary().getSources()) {
+                                                       selectTargets.add(source);
+                                               }
+                                       } catch (IOException e) {
+                                               Instance.getInstance().getTraceHandler().error(e);
+                                       }
+
+                                       showTarget = true;
+                               } else {
+                                       selectTargets.clear();
+                                       selectTargets.add("(show all)");
+                                       try {
+                                               for (String author : reader.getLibrary().getAuthors()) {
+                                                       selectTargets.add(author);
+                                               }
+                                       } catch (IOException e) {
+                                               Instance.getInstance().getTraceHandler().error(e);
+                                       }
+
+                                       showTarget = true;
+                               }
+
+                               selectTargetBox.setVisible(showTarget);
+                               selectTargetBox.setEnabled(showTarget);
+                               if (showTarget) {
+                                       selectTargetBox.reflowData();
+                               }
+
+                               selectTargetBox.setText(selectTargets.get(0));
+                               if (showTarget) {
+                                       TuiReaderMainWindow.this.activate(selectTargetBox);
+                               } else {
+                                       TuiReaderMainWindow.this.activate(list);
+                               }
+                       }
+               };
+
+               selectBox = addComboBox(0, 0, 10, selects, 0, -1, onSelect);
+
+               selectTargetBox = addComboBox(0, 0, 0, selectTargets, 0, -1,
+                               new TAction() {
+                                       @Override
+                                       public void DO() {
+                                               if (selectTargetBox.getText().equals(
+                                                               selectTargets.get(0))) {
+                                                       setMode(mode, null);
+                                               } else {
+                                                       setMode(mode, selectTargetBox.getText());
+                                               }
+                                       }
+                               });
+
+               // Set defaults
+               onSelect.DO();
+
+               TSizeConstraint.setSize(sizeConstraints, lblSelect, 5, 3, null, null);
+               TSizeConstraint.setSize(sizeConstraints, selectBox, 15, 3, -5, null);
+               TSizeConstraint.setSize(sizeConstraints, selectTargetBox, 15, 4, -5,
+                               null);
+       }
+
+       @Override
+       public void onResize(TResizeEvent resize) {
+               super.onResize(resize);
+               TSizeConstraint.resize(sizeConstraints);
+       }
+
        @Override
        public void onClose() {
                setVisible(false);
@@ -93,38 +234,49 @@ class TuiReaderMainWindow extends TWindow {
        }
 
        /**
-        * Change the source filter and display all stories matching this source.
-        * 
-        * @param source
-        *            the new source or NULL for all sources
+        * Refresh the list of stories displayed in this library.
+        * <p>
+        * Will take the current settings into account (filter, source...).
         */
-       public void setSource(String source) {
-               this.source = source;
-               refreshStories();
-       }
-
        public void refreshStories() {
-               List<MetaData> metas = reader.getLibrary().getListBySource(source);
+               List<MetaData> metas;
+
+               try {
+                       if (mode == Mode.SOURCE) {
+                               metas = reader.getLibrary().getListBySource(target);
+                       } else if (mode == Mode.AUTHOR) {
+                               metas = reader.getLibrary().getListByAuthor(target);
+                       } else {
+                               metas = reader.getLibrary().getList();
+                       }
+               } catch (IOException e) {
+                       Instance.getInstance().getTraceHandler().error(e);
+                       metas = new ArrayList<MetaData>();
+               }
+
                setMetas(metas);
        }
 
        /**
-        * Update the list of stories displayed in this {@link TWindow}.
+        * Change the author/source filter and display all stories matching this
+        * target.
         * 
-        * @param meta
-        *            the new (unique) story to display
+        * @param mode
+        *            the new mode or NULL for no sorting
+        * @param target
+        *            the actual target for the given mode, or NULL for all of them
         */
-       public void setMeta(MetaData meta) {
-               List<MetaData> metas = new ArrayList<MetaData>();
-               if (meta != null) {
-                       metas.add(meta);
-               }
-
-               setMetas(metas);
+       public void setMode(Mode mode, String target) {
+               this.mode = mode;
+               this.target = target;
+               refreshStories();
        }
 
        /**
         * Update the list of stories displayed in this {@link TWindow}.
+        * <p>
+        * If a filter is set, only the stories which pass the filter will be
+        * displayed.
         * 
         * @param metas
         *            the new list of stories to display
@@ -135,12 +287,19 @@ class TuiReaderMainWindow extends TWindow {
 
                if (metas != null) {
                        for (MetaData meta : metas) {
-                               listKeys.add(meta);
-                               listItems.add(desc(meta));
+                               String desc = desc(meta);
+                               if (filter.isEmpty()
+                                               || desc.toLowerCase().contains(filter.toLowerCase())) {
+                                       listKeys.add(meta);
+                                       listItems.add(desc);
+                               }
                        }
                }
 
                list.setList(listItems);
+               if (listItems.size() > 0) {
+                       list.setSelectedIndex(0);
+               }
        }
 
        public MetaData getSelectedMeta() {
@@ -155,9 +314,9 @@ class TuiReaderMainWindow extends TWindow {
                try {
                        reader.setChapter(-1);
                        reader.setMeta(meta);
-                       reader.read();
+                       reader.read(false);
                } catch (IOException e) {
-                       Instance.getTraceHandler().error(e);
+                       Instance.getInstance().getTraceHandler().error(e);
                }
        }
 
@@ -165,16 +324,26 @@ class TuiReaderMainWindow extends TWindow {
                return String.format("%5s: %s", meta.getLuid(), meta.getTitle());
        }
 
+       @Override
+       public void onCommand(TCommandEvent command) {
+               if (command.getCmd().equals(TuiReaderApplication.CMD_EXIT)) {
+                       TuiReaderApplication.close(this);
+               } else {
+                       // Handle our own event if needed here
+                       super.onCommand(command);
+               }
+       }
+
        @Override
        public void onMenu(TMenuEvent menu) {
                MetaData meta = getSelectedMeta();
                if (meta != null) {
                        switch (menu.getId()) {
-                       case TuiReaderApplication.MENU_OPEN:
+                       case TuiReaderApplication.MENU_FILE_OPEN:
                                readStory(meta);
 
                                return;
-                       case TuiReaderApplication.MENU_EXPORT:
+                       case TuiReaderApplication.MENU_FILE_EXPORT:
 
                                try {
                                        // TODO: choose type, pg, error
@@ -188,6 +357,7 @@ class TuiReaderMainWindow extends TWindow {
                                }
 
                                return;
+
                        case -1:
                                try {
                                        reader.getLibrary().delete(meta.getLuid());