001    // This file is part of the Attempto Java Packages.
002    // Copyright 2008-2009, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
003    //
004    // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the
005    // terms of the GNU Lesser General Public License as published by the Free Software Foundation,
006    // either version 3 of the License, or (at your option) any later version.
007    //
008    // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY
009    // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
010    // PURPOSE. See the GNU Lesser General Public License for more details.
011    //
012    // You should have received a copy of the GNU Lesser General Public License along with the Attempto
013    // Java Packages. If not, see http://www.gnu.org/licenses/.
014    
015    package ch.uzh.ifi.attempto.acewiki.gui.page;
016    
017    import java.util.ArrayList;
018    import java.util.Collections;
019    
020    import nextapp.echo2.app.ApplicationInstance;
021    import nextapp.echo2.app.Column;
022    import nextapp.echo2.app.Extent;
023    import nextapp.echo2.app.Font;
024    import nextapp.echo2.app.Insets;
025    import nextapp.echo2.app.Row;
026    import nextapp.echo2.app.event.ActionEvent;
027    import nextapp.echo2.app.event.ActionListener;
028    import ch.uzh.ifi.attempto.acewiki.Wiki;
029    import ch.uzh.ifi.attempto.acewiki.core.ontology.OntologyElement;
030    import ch.uzh.ifi.attempto.acewiki.gui.IndexBar;
031    import ch.uzh.ifi.attempto.acewiki.gui.ListItem;
032    import ch.uzh.ifi.attempto.acewiki.gui.Title;
033    import ch.uzh.ifi.attempto.acewiki.gui.WikiLink;
034    import ch.uzh.ifi.attempto.echocomp.GeneralButton;
035    import ch.uzh.ifi.attempto.echocomp.SolidLabel;
036    import ch.uzh.ifi.attempto.echocomp.TextField;
037    import ch.uzh.ifi.attempto.echocomp.VSpace;
038    
039    /**
040     * This class represents a page on which the user can search for articles.
041     * 
042     * @author Tobias Kuhn
043     */
044    public class SearchPage extends WikiPage implements ActionListener {
045    
046            private static final long serialVersionUID = 7192145568847087174L;
047            
048            private static final int pageSize = 20;
049            
050            private int chosenPage = 0;
051            private ArrayList<OntologyElement> searchResult;
052            
053            private Column resultColumn = new Column();
054            private IndexBar indexBar;
055            private TextField textField;
056            
057            /**
058             * Creates a new search page.
059             * 
060             * @param wiki The wiki instance.
061             * @param text The search text.
062             */
063            public SearchPage(Wiki wiki, String text) {
064                    super(wiki, new Title("Search", true));
065                    
066                    addTab("Main Page", this);
067                    addTab("Index", this);
068                    addSelectedTab("Search");
069                    
070                    add(new VSpace(15));
071                    
072                    addHeadline("Search word");
073                    add(new VSpace(10));
074                    
075                    Row textFieldRow = new Row();
076                    textFieldRow.setInsets(new Insets(10, 0));
077                    textFieldRow.setCellSpacing(new Extent(5));
078                    textFieldRow.add(textField = new TextField(this));
079                    textField.setWidth(new Extent(300));
080                    textField.addActionListener(this);
081                    textField.setText(text);
082                    textFieldRow.add(new GeneralButton("Search", this));
083                    add(textFieldRow);
084                    
085                    add(new VSpace(15));
086                    
087                    addHeadline("Results");
088                    add(new VSpace(10));
089                    
090                    indexBar = new IndexBar("Page:", 0, this);
091                    add(indexBar);
092                    
093                    resultColumn.setInsets(new Insets(10, 2, 5, 20));
094                    resultColumn.setCellSpacing(new Extent(2));
095                    add(resultColumn);
096                    
097                    update();
098            }
099            
100            protected void doUpdate() {
101                    ApplicationInstance.getActive().setFocusedComponent(textField);
102                    
103                    resultColumn.removeAll();
104                    if (textField.getText().length() == 0) {
105                            indexBar.setVisible(false);
106                            resultColumn.add(new SolidLabel("(enter a search text)", Font.ITALIC, 10));
107                            return;
108                    }
109                    
110                    ArrayList<OntologyElement> elements = new ArrayList<OntologyElement>(getWiki().getOntologyElements());
111                    Collections.sort(elements);
112                    
113                    searchResult = new ArrayList<OntologyElement>();
114                    for (OntologyElement e : elements) {
115                            for (String w : e.getWords()) {
116                                    if (w == null) continue;
117                                    if (w.toLowerCase().replace("_", " ").contains(textField.getText().toLowerCase().replace("_", " "))) {
118                                            searchResult.add(e);
119                                            break;
120                                    }
121                            }
122                    }
123                    if (searchResult.size() == 0) {
124                            indexBar.setVisible(false);
125                            resultColumn.add(new SolidLabel("(nothing found)", Font.ITALIC, 10));
126                    } else {
127                            int i = ((searchResult.size()-1) / pageSize) + 1;
128                            if (chosenPage > i) chosenPage = 0;
129                            indexBar.setNumbers(i);
130                            indexBar.setActiveButton(chosenPage);
131                            updatePage();
132                    }
133            }
134            
135            private void updatePage() {
136                    resultColumn.removeAll();
137                    
138                    indexBar.setVisible(searchResult.size() > pageSize);
139                    
140                    int max = searchResult.size();
141                    if (max > (chosenPage + 1) * pageSize) max = (chosenPage + 1) * pageSize;
142                    
143                    for (int i = chosenPage * pageSize; i < max; i++) {
144                            resultColumn.add(new ListItem(new WikiLink(searchResult.get(i), getWiki())));
145                    }
146            }
147            
148            public void actionPerformed(ActionEvent e) {
149                    if (e.getSource() == indexBar) {
150                            chosenPage = Integer.parseInt(e.getActionCommand()) - 1;
151                            log("page", "pressed: page " + (chosenPage+1));
152                            updatePage();
153                    } else if ("Main Page".equals(e.getActionCommand())) {
154                            getWiki().showStartPage();
155                    } else if ("Index".equals(e.getActionCommand())) {
156                            getWiki().showIndexPage();
157                    } else {
158                            log("page", "search for " + textField.getText());
159                            update();
160                    }
161            }
162            
163            public boolean equals(Object obj) {
164                    return obj instanceof SearchPage;
165            }
166            
167            public String toString() {
168                    return "-SEARCH-";
169            }
170    
171    }