X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Ffanfix%2Freader%2Fui%2FGuiReaderSearch.java;h=172f0fa822f379de921988608f65016ddf5ad83c;hb=415c74543f4cdb92b32b495ac73c961f4f377387;hp=04c1dad1071b89ef5d1e3a9c794be4c5b187ca3d;hpb=d16065ecb5ab854a71f385ed8c47012184139783;p=fanfix.git diff --git a/src/be/nikiroo/fanfix/reader/ui/GuiReaderSearch.java b/src/be/nikiroo/fanfix/reader/ui/GuiReaderSearch.java index 04c1dad..172f0fa 100644 --- a/src/be/nikiroo/fanfix/reader/ui/GuiReaderSearch.java +++ b/src/be/nikiroo/fanfix/reader/ui/GuiReaderSearch.java @@ -1,6 +1,7 @@ package be.nikiroo.fanfix.reader.ui; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; import java.awt.event.ActionEvent; @@ -10,13 +11,17 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; +import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; +import javax.swing.ListCellRenderer; import be.nikiroo.fanfix.Instance; import be.nikiroo.fanfix.data.MetaData; @@ -36,19 +41,23 @@ public class GuiReaderSearch extends JFrame { private List supportTypes; private SupportType supportType; + private boolean searchByTags; private List tags; private String keywords; private int page; private int maxPage; - private JComboBox comboSupportTypes; + private JPanel tagBars; + + private JComboBox comboSupportTypes; private JTabbedPane searchTabs; + private JTextField keywordsField; + private JButton submitKeywords; private boolean seeWordcount; private GuiReaderGroup books; public GuiReaderSearch(final GuiReader reader) { - // TODO: i18n super("Browse stories"); setLayout(new BorderLayout()); setSize(800, 600); @@ -56,6 +65,7 @@ public class GuiReaderSearch extends JFrame { tags = new ArrayList(); page = 1; // TODO maxPage = -1; + searchByTags = false; supportTypes = new ArrayList(); for (SupportType type : SupportType.values()) { @@ -65,23 +75,25 @@ public class GuiReaderSearch extends JFrame { } supportType = supportTypes.isEmpty() ? null : supportTypes.get(0); - JPanel top = new JPanel(new BorderLayout()); - comboSupportTypes = new JComboBox( + comboSupportTypes = new JComboBox( supportTypes.toArray(new SupportType[] {})); comboSupportTypes.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - setSupportType((SupportType) comboSupportTypes + updateSupportType((SupportType) comboSupportTypes .getSelectedItem()); } }); - top.add(comboSupportTypes, BorderLayout.NORTH); + JPanel searchSites = new JPanel(new BorderLayout()); + searchSites.add(comboSupportTypes, BorderLayout.CENTER); + searchSites.add(new JLabel(" " + "Website : "), BorderLayout.WEST); - // TODO: i18n searchTabs = new JTabbedPane(); searchTabs.addTab("By name", createByNameSearchPanel()); searchTabs.addTab("By tags", createByTagSearchPanel()); + JPanel top = new JPanel(new BorderLayout()); + top.add(searchSites, BorderLayout.NORTH); top.add(searchTabs, BorderLayout.CENTER); add(top, BorderLayout.NORTH); @@ -106,27 +118,22 @@ public class GuiReaderSearch extends JFrame { JScrollPane scroll = new JScrollPane(books); scroll.getVerticalScrollBar().setUnitIncrement(16); add(scroll, BorderLayout.CENTER); - } - public void setSupportType(SupportType supportType) { - this.supportType = supportType; - comboSupportTypes.setSelectedItem(supportType); - // TODO: reset all + updateTags(null); } private JPanel createByNameSearchPanel() { JPanel byName = new JPanel(new BorderLayout()); - final JTextField keywordsField = new JTextField(); + keywordsField = new JTextField(); byName.add(keywordsField, BorderLayout.CENTER); - // TODO: i18n - JButton submit = new JButton("Search"); - byName.add(submit, BorderLayout.EAST); + submitKeywords = new JButton("Search"); + byName.add(submitKeywords, BorderLayout.EAST); // TODO: ENTER -> search - submit.addActionListener(new ActionListener() { + submitKeywords.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { search(supportType, keywordsField.getText(), page, 0); @@ -138,54 +145,35 @@ public class GuiReaderSearch extends JFrame { private JPanel createByTagSearchPanel() { JPanel byTag = new JPanel(); - JPanel searchBars = new JPanel(); - add(searchBars, BorderLayout.NORTH); + tagBars = new JPanel(); + tagBars.setLayout(new BoxLayout(tagBars, BoxLayout.Y_AXIS)); + byTag.add(tagBars, BorderLayout.NORTH); return byTag; } - // item 0 = no selction, else = default selection - public void search(final SupportType searchOn, final String keywords, - final int page, final int item) { - setSupportType(searchOn); - this.keywords = keywords; - this.page = page; - - new Thread(new Runnable() { - @Override - public void run() { - BasicSearchable search = BasicSearchable - .getSearchable(searchOn); - - if (page <= 0) { - int maxPage = -1; - try { - maxPage = search.searchPages(keywords); - } catch (IOException e) { - Instance.getTraceHandler().error(e); - } - updateBooks(new ArrayList()); - updatePages(0, maxPage); - } else { - List infos = new ArrayList(); - try { - for (MetaData meta : search.search(keywords, page)) { - infos.add(GuiReaderBookInfo.fromMeta(meta)); - } - } catch (IOException e) { - Instance.getTraceHandler().error(e); - } - - updateBooks(infos); - updatePages(page, maxPage); + private void updateSupportType(SupportType supportType) { + if (supportType != this.supportType) { + this.supportType = supportType; + comboSupportTypes.setSelectedItem(supportType); + books.clear(); + updateTags(null); + } + } - // ! 1-based index ! - if (item > 0 && item <= books.getBooksCount()) { - // TODO: "click" on item ITEM + private void updateSearchBy(final boolean byTag) { + if (byTag != this.searchByTags) { + inUi(new Runnable() { + @Override + public void run() { + if (!byTag) { + searchTabs.setSelectedIndex(0); + } else { + searchTabs.setSelectedIndex(1); } } - } - }).start(); + }); + } } private void updatePages(final int page, final Integer maxPage) { @@ -201,76 +189,296 @@ public class GuiReaderSearch extends JFrame { }); } + // cannot be NULL + private void updateKeywords(final String keywords) { + if (!keywords.equals(this.keywords)) { + inUi(new Runnable() { + @Override + public void run() { + GuiReaderSearch.this.keywords = keywords; + keywordsField.setText(keywords); + } + }); + } + } + + // can be NULL, for base tags + private void updateTags(final SearchableTag tag) { + final List parents = new ArrayList(); + SearchableTag parent = (tag == null) ? null : tag; + while (parent != null) { + parents.add(parent); + parent = parent.getParent(); + } + + inUi(new Runnable() { + @Override + public void run() { + tagBars.invalidate(); + tagBars.removeAll(); + + // TODO: Slow UI + // TODO: select the right one + try { + addTagBar(BasicSearchable.getSearchable(supportType) + .getTags(), tag); + } catch (IOException e) { + error(e); + } + + for (int i = parents.size() - 1; i >= 0; i--) { + SearchableTag parent = parents.get(i); + addTagBar(parent.getChildren(), parent); + } + + tagBars.validate(); + } + }); + } + private void updateBooks(final List infos) { + setWaitingScreen(true); inUi(new Runnable() { @Override public void run() { books.refreshBooks(infos, seeWordcount); + setWaitingScreen(false); } }); } - private void searchTag(SupportType searchOn, int page, int item, - boolean sync, Integer... tags) throws IOException { + private void addTagBar(List tags, + final SearchableTag selected) { + tags.add(0, null); - BasicSearchable search = BasicSearchable.getSearchable(searchOn); - SearchableTag stag = search.getTag(tags); + final JComboBox combo = new JComboBox( + tags.toArray(new SearchableTag[] {})); + combo.setSelectedItem(selected); - if (stag == null) { - // TODO i18n - System.out.println("Known tags: "); - int i = 1; - for (SearchableTag s : search.getTags()) { - System.out.println(String.format("%d: %s", i, s.getName())); - i++; - } - } else { - if (page <= 0) { - if (stag.isLeaf()) { - search.search(stag, 1); - System.out.println(stag.getPages()); + final ListCellRenderer basic = combo.getRenderer(); + + combo.setRenderer(new ListCellRenderer() { + @Override + public Component getListCellRendererComponent( + JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + + Object displayValue = value; + if (value instanceof SearchableTag) { + displayValue = ((SearchableTag)value).getName(); } else { - System.out.println(stag.getCount()); + displayValue = "Select a tag..."; + cellHasFocus = false; + isSelected = false; } - } else { - List metas = null; - List subtags = null; - int count; - - if (stag.isLeaf()) { - metas = search.search(stag, page); - count = metas.size(); - } else { - subtags = stag.getChildren(); - count = subtags.size(); + + Component rep = basic.getListCellRendererComponent(list, + displayValue, index, isSelected, cellHasFocus); + + if (value == null) { + rep.setForeground(Color.GRAY); } - if (item > 0) { - if (item <= count) { - if (metas != null) { - MetaData meta = metas.get(item - 1); - // displayStory(meta); - } else { - SearchableTag subtag = subtags.get(item - 1); - // displayTag(subtag); + return rep; + } + }); + + combo.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + final SearchableTag tag = (SearchableTag) combo + .getSelectedItem(); + if (tag != null) { + addTagBar(tag, new Runnable() { + @Override + public void run() { + // TODO: stories if needed + setWaitingScreen(false); } - } else { - System.out.println("Invalid item: only " + count - + " items found"); + }); + } + } + }); + + tagBars.add(combo); + } + + // async, add children of tag, NULL = base tags + private void addTagBar(final SearchableTag tag, final Runnable inUi) { + new Thread(new Runnable() { + @Override + public void run() { + BasicSearchable searchable = BasicSearchable + .getSearchable(supportType); + + List children = new ArrayList(); + if (tag == null) { + try { + List baseTags = searchable.getTags(); + children = baseTags; + } catch (IOException e) { + error(e); } } else { - if (metas != null) { - // TODO i18n - System.out.println(String.format("Content of %s: ", - stag.getFqName())); - // displayStories(metas); + try { + searchable.fillTag(tag); + } catch (IOException e) { + error(e); + } + + if (!tag.isLeaf()) { + children = tag.getChildren(); } else { - // TODO i18n - System.out.println(String.format("Subtags of %s: ", - stag.getFqName())); - // displayTags(subtags); + children = null; + // TODO: stories } } + + final List fchildren = children; + inUi(new Runnable() { + @Override + public void run() { + if (fchildren != null) { + addTagBar(fchildren, tag); + } + + if (inUi != null) { + inUi.run(); + } + } + }); + } + }).start(); + } + + // item 0 = no selection, else = default selection + public void search(final SupportType searchOn, final String keywords, + final int page, final int item) { + + setWaitingScreen(true); + + updateSupportType(searchOn); + updateSearchBy(false); + updateKeywords(keywords); + updatePages(page, maxPage); + + new Thread(new Runnable() { + @Override + public void run() { + BasicSearchable search = BasicSearchable + .getSearchable(searchOn); + + int maxPage = -1; + try { + maxPage = search.searchPages(keywords); + } catch (IOException e) { + error(e); + } + + if (page <= 0) { + updateBooks(new ArrayList()); + updatePages(0, maxPage); + } else { + List results; + try { + results = search.search(keywords, page); + } catch (IOException e) { + error(e); + results = new ArrayList(); + } + + search(results, page, maxPage, item); + + // ! 1-based index ! + if (item > 0 && item <= books.getBooksCount()) { + // TODO: "click" on item ITEM + } + } + + setWaitingScreen(false); + } + }).start(); + } + + // tag: must be filled (or NULL for base tags) + public void searchTag(final SupportType searchOn, final int page, + final int item, final SearchableTag tag) { + + setWaitingScreen(true); + + updateSupportType(searchOn); + updateSearchBy(true); + updateTags(tag); + updatePages(page, maxPage); + + new Thread(new Runnable() { + @Override + public void run() { + BasicSearchable search = BasicSearchable + .getSearchable(searchOn); + + if (tag != null) { + int maxPage = 0; + try { + maxPage = search.searchPages(tag); + } catch (IOException e) { + error(e); + } + + updatePages(page, maxPage); + + if (page > 0) { + List metas = new ArrayList(); + + if (tag.isLeaf()) { + try { + metas = search.search(tag, page); + } catch (IOException e) { + error(e); + } + } else { + List subtags = tag.getChildren(); + if (item > 0 && item <= subtags.size()) { + SearchableTag subtag = subtags.get(item - 1); + try { + metas = search.search(subtag, page); + maxPage = subtag.getPages(); + } catch (IOException e) { + error(e); + } + } + } + + updatePages(page, maxPage); + search(metas, page, maxPage, item); + } + } + + setWaitingScreen(false); + } + }).start(); + } + + // item 0 = no selection, else = default selection + public void search(final List results, final int page, + final int maxPage, final int item) { + + updatePages(page, maxPage); + + if (page <= 0) { + updateBooks(new ArrayList()); + updatePages(0, maxPage); + } else { + List infos = new ArrayList(); + for (MetaData meta : results) { + infos.add(GuiReaderBookInfo.fromMeta(meta)); + } + + updateBooks(infos); + + // ! 1-based index ! + if (item > 0 && item <= books.getBooksCount()) { + // TODO: "click" on item ITEM } } } @@ -286,17 +494,32 @@ public class GuiReaderSearch extends JFrame { * @param run * the action to run */ - public void inUi(final Runnable run) { + private void inUi(final Runnable run) { if (EventQueue.isDispatchThread()) { run.run(); } else { try { EventQueue.invokeAndWait(run); } catch (InterruptedException e) { - Instance.getTraceHandler().error(e); + error(e); } catch (InvocationTargetException e) { - Instance.getTraceHandler().error(e); + error(e); } } } + + private void error(Exception e) { + Instance.getTraceHandler().error(e); + } + + private void setWaitingScreen(final boolean waiting) { + inUi(new Runnable() { + @Override + public void run() { + GuiReaderSearch.this.setEnabled(!waiting); + books.setEnabled(!waiting); + submitKeywords.setEnabled(!waiting); + } + }); + } }