+++ /dev/null
-package be.nikiroo.fanfix.reader.ui;
-
-import java.awt.BorderLayout;
-import java.util.List;
-
-import javax.swing.JPanel;
-import javax.swing.JTabbedPane;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import be.nikiroo.fanfix.data.MetaData;
-import be.nikiroo.fanfix.searchable.BasicSearchable;
-import be.nikiroo.fanfix.searchable.SearchableTag;
-import be.nikiroo.fanfix.supported.SupportType;
-
-/**
- * This panel represents a search panel that works for keywords and tags based
- * searches.
- *
- * @author niki
- */
-public class GuiReaderSearchByPanel extends JPanel {
- private static final long serialVersionUID = 1L;
-
- private Waitable waitable;
-
- private boolean searchByTags;
- private JTabbedPane searchTabs;
- private GuiReaderSearchByNamePanel byName;
- private GuiReaderSearchByTagPanel byTag;
-
- /**
- * This interface represents an item that wan be put in "wait" mode. It is
- * supposed to be used for long running operations during which we want to
- * disable UI interactions.
- * <p>
- * It also allows reporting an event to the item.
- *
- * @author niki
- */
- public interface Waitable {
- /**
- * Set the item in wait mode, blocking it from accepting UI input.
- *
- * @param waiting
- * TRUE for wait more, FALSE to restore normal mode
- */
- public void setWaiting(boolean waiting);
-
- /**
- * Notify the {@link Waitable} that an event occured (i.e., new stories
- * were found).
- */
- public void fireEvent();
- }
-
- /**
- * Create a new {@link GuiReaderSearchByPanel}.
- *
- * @param waitable
- * the waitable we can wait on for long UI operations
- */
- public GuiReaderSearchByPanel(Waitable waitable) {
- setLayout(new BorderLayout());
-
- this.waitable = waitable;
- searchByTags = false;
-
- byName = new GuiReaderSearchByNamePanel(waitable);
- byTag = new GuiReaderSearchByTagPanel(waitable);
-
- searchTabs = new JTabbedPane();
- searchTabs.addTab("By name", byName);
- searchTabs.addTab("By tags", byTag);
- searchTabs.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- searchByTags = (searchTabs.getSelectedComponent() == byTag);
- }
- });
-
- add(searchTabs, BorderLayout.CENTER);
- updateSearchBy(searchByTags);
- }
-
- /**
- * Set the new {@link SupportType}.
- * <p>
- * This operation can be long and should be run outside the UI thread.
- * <p>
- * Note that if a non-searchable {@link SupportType} is used, an
- * {@link IllegalArgumentException} will be thrown.
- *
- * @param supportType
- * the support mode, must be searchable or NULL
- *
- * @throws IllegalArgumentException
- * if the {@link SupportType} is not NULL but not searchable
- * (see {@link BasicSearchable#getSearchable(SupportType)})
- */
- public void setSupportType(SupportType supportType) {
- BasicSearchable searchable = BasicSearchable.getSearchable(supportType);
- if (searchable == null && supportType != null) {
- throw new IllegalArgumentException("Unupported support type: "
- + supportType);
- }
-
- byName.setSearchable(searchable);
- byTag.setSearchable(searchable);
- }
-
- /**
- * The currently displayed page of result for the current search (see the
- * <tt>page</tt> parameter of
- * {@link GuiReaderSearchByPanel#search(String, int, int)} or
- * {@link GuiReaderSearchByPanel#searchTag(SupportType, int, int, SearchableTag)}
- * ).
- *
- * @return the currently displayed page of results
- */
- public int getPage() {
- if (!searchByTags) {
- return byName.getPage();
- }
-
- return byTag.getPage();
- }
-
- /**
- * The number of pages of result for the current search (see the
- * <tt>page</tt> parameter of
- * {@link GuiReaderSearchByPanel#search(String, int, int)} or
- * {@link GuiReaderSearchByPanel#searchTag(SupportType, int, int, SearchableTag)}
- * ).
- * <p>
- * For an unknown number or when not applicable, -1 is returned.
- *
- * @return the number of pages of results or -1
- */
- public int getMaxPage() {
- if (!searchByTags) {
- return byName.getMaxPage();
- }
-
- return byTag.getMaxPage();
- }
-
- /**
- * Set the page of results to display for the current search. This will
- * cause {@link Waitable#fireEvent()} to be called if needed.
- * <p>
- * This operation can be long and should be run outside the UI thread.
- *
- * @param page
- * the page of results to set
- *
- * @throw IndexOutOfBoundsException if the page is out of bounds
- */
- public void setPage(int page) {
- if (searchByTags) {
- searchTag(byTag.getCurrentTag(), page, 0);
- } else {
- search(byName.getCurrentKeywords(), page, 0);
- }
- }
-
- /**
- * The currently loaded stories (the result of the latest search).
- *
- * @return the stories
- */
- public List<MetaData> getStories() {
- if (!searchByTags) {
- return byName.getStories();
- }
-
- return byTag.getStories();
- }
-
- /**
- * Return the currently selected story (the <tt>item</tt>) if it was
- * specified in the latest, or 0 if not.
- * <p>
- * Note: this is thus a 1-based index, <b>not</b> a 0-based index.
- *
- * @return the item
- */
- public int getStoryItem() {
- if (!searchByTags) {
- return byName.getStoryItem();
- }
-
- return byTag.getStoryItem();
- }
-
- /**
- * Update the kind of searches to make: search by keywords or search by tags
- * (it will impact what the user can see and interact with on the UI).
- *
- * @param byTag
- * TRUE for tag-based searches, FALSE for keywords-based searches
- */
- private void updateSearchBy(final boolean byTag) {
- GuiReaderSearchFrame.inUi(new Runnable() {
- @Override
- public void run() {
- if (!byTag) {
- searchTabs.setSelectedIndex(0);
- } else {
- searchTabs.setSelectedIndex(1);
- }
- }
- });
- }
-
- /**
- * Search for the given terms on the currently selected searchable. This
- * will cause {@link Waitable#fireEvent()} to be called if needed.
- * <p>
- * This operation can be long and should be run outside the UI thread.
- *
- * @param keywords
- * the keywords to search for
- * @param page
- * the page of results to load
- * @param item
- * the item to select (or 0 for none by default)
- *
- * @throw IndexOutOfBoundsException if the page is out of bounds
- */
- public void search(final String keywords, final int page, final int item) {
- updateSearchBy(false);
- byName.search(keywords, page, item);
- waitable.fireEvent();
- }
-
- /**
- * Search for the given tag on the currently selected searchable. This will
- * cause {@link Waitable#fireEvent()} to be called if needed.
- * <p>
- * If the tag contains children tags, those will be displayed so you can
- * select them; if the tag is a leaf tag, the linked stories will be
- * displayed.
- * <p>
- * This operation can be long and should be run outside the UI thread.
- *
- * @param tag
- * the tag to search for, or NULL for base tags
- * @param page
- * the page of results to load
- * @param item
- * the item to select (or 0 for none by default)
- *
- * @throw IndexOutOfBoundsException if the page is out of bounds
- */
- public void searchTag(final SearchableTag tag, final int page,
- final int item) {
- updateSearchBy(true);
- byTag.searchTag(tag, page, item);
- waitable.fireEvent();
- }
-
- /**
- * Enables or disables this component, depending on the value of the
- * parameter <code>b</code>. An enabled component can respond to user input
- * and generate events. Components are enabled initially by default.
- * <p>
- * Disabling this component will also affect its children.
- *
- * @param b
- * If <code>true</code>, this component is enabled; otherwise
- * this component is disabled
- */
- @Override
- public void setEnabled(boolean b) {
- super.setEnabled(b);
- searchTabs.setEnabled(b);
- byName.setEnabled(b);
- byTag.setEnabled(b);
- }
-}