001 // This file is part of AceWiki.
002 // Copyright 2008-2012, AceWiki developers.
003 //
004 // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
005 // Lesser General Public License as published by the Free Software Foundation, either version 3 of
006 // the License, or (at your option) any later version.
007 //
008 // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010 // Lesser General Public License for more details.
011 //
012 // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
013 // not, see http://www.gnu.org/licenses/.
014
015 package ch.uzh.ifi.attempto.acewiki.gui;
016
017 import java.util.ArrayList;
018 import java.util.Collections;
019 import java.util.Comparator;
020 import java.util.List;
021
022 import nextapp.echo.app.Column;
023 import nextapp.echo.app.Extent;
024 import nextapp.echo.app.Font;
025 import nextapp.echo.app.Insets;
026 import nextapp.echo.app.Row;
027 import nextapp.echo.app.event.ActionEvent;
028 import nextapp.echo.app.event.ActionListener;
029 import ch.uzh.ifi.attempto.acewiki.Task;
030 import ch.uzh.ifi.attempto.acewiki.core.Concept;
031 import ch.uzh.ifi.attempto.acewiki.core.Individual;
032 import ch.uzh.ifi.attempto.acewiki.core.OntologyElement;
033 import ch.uzh.ifi.attempto.acewiki.core.CachingReasoner;
034 import ch.uzh.ifi.attempto.acewiki.core.Sentence;
035 import ch.uzh.ifi.attempto.acewiki.core.StatementFactory;
036 import ch.uzh.ifi.attempto.echocomp.SolidLabel;
037 import ch.uzh.ifi.attempto.echocomp.VSpace;
038
039 /**
040 * This class represents a page that shows all individuals that belong to a certain concept.
041 *
042 * @author Tobias Kuhn
043 */
044 public class IndividualsPage extends WikiPage implements ActionListener {
045
046 private static final long serialVersionUID = 4273564259160715684L;
047
048 private static final int pageSize = 50;
049
050 private ConceptPage page;
051 private Column individualsColumn = new Column();
052 private int chosenPage = 0;
053 private Title title;
054
055 /**
056 * Creates a new individuals page.
057 *
058 * @param page The main page that contains the article.
059 */
060 public IndividualsPage(ConceptPage page) {
061 super(page.getWiki());
062 this.page = page;
063
064 addTab("Article", this);
065 addTab("References", this);
066 addSelectedTab("Individuals");
067 addTab("Hierarchy", this);
068
069 OntologyElement oe = page.getOntologyElement();
070 title = new Title(getHeading(oe), "- Individuals", oe.getType(), this);
071 add(title);
072 addHorizontalLine();
073
074 add(individualsColumn);
075 }
076
077 protected void doUpdate() {
078 title.setText(getHeading(page.getOntologyElement()));
079 individualsColumn.removeAll();
080
081 final Column waitComp = new Column();
082 waitComp.setInsets(new Insets(10, 0, 0, 0));
083 waitComp.add(new RecalcIcon("This list is being updated."));
084
085 CachingReasoner cr = getWiki().getOntology().getReasoner();
086
087 if (cr.areCachedIndividualsUpToDate((Concept) page.getOntologyElement())) {
088 individualsColumn.add(new VSpace(18));
089 individualsColumn.add(new IndividualsComponent(true));
090 } else {
091 individualsColumn.add(new VSpace(4));
092 individualsColumn.add(waitComp);
093 individualsColumn.add(new IndividualsComponent(true));
094 page.getWiki().enqueueWeakAsyncTask(new Task() {
095
096 private IndividualsComponent delayedComp;
097
098 public void run() {
099 delayedComp = new IndividualsComponent(false);
100 }
101
102 public void updateGUI() {
103 individualsColumn.removeAll();
104 individualsColumn.add(new VSpace(18));
105 individualsColumn.add(delayedComp);
106 }
107
108 });
109 }
110 }
111
112 public void actionPerformed(ActionEvent e) {
113 if ("Article".equals(e.getActionCommand())) {
114 log("page", "pressed: article");
115 getWiki().showPage(page);
116 } else if ("References".equals(e.getActionCommand())) {
117 log("page", "pressed: references");
118 getWiki().showPage(new ReferencesPage(page));
119 } else if ("Hierarchy".equals(e.getActionCommand())) {
120 log("page", "pressed: hierarchy");
121 getWiki().showPage(new HierarchyPage(page));
122 } else if (e.getSource() == title) {
123 getWiki().showEditorWindow(page.getOntologyElement());
124 }
125 }
126
127 public boolean equals(Object obj) {
128 if (obj instanceof IndividualsPage) {
129 return page.equals(((IndividualsPage) obj).page);
130 }
131 return false;
132 }
133
134 public boolean isExpired() {
135 return page.isExpired();
136 }
137
138 public String toString() {
139 return "-IND- " + page.getOntologyElement().getWord();
140 }
141
142
143 private class IndividualsComponent extends Column implements ActionListener {
144
145 private static final long serialVersionUID = -2897618204616741456L;
146
147 private Column sentencesColumn = new Column();
148 private IndexBar indexBar;
149 private List<Sentence> sentences;
150
151
152 public IndividualsComponent(boolean cached) {
153 indexBar = new IndexBar("Page:", 0, this);
154 add(indexBar);
155
156 sentencesColumn.setInsets(new Insets(10, 2, 5, 20));
157 sentencesColumn.setCellSpacing(new Extent(2));
158 add(sentencesColumn);
159
160 Concept concept = (Concept) page.getOntologyElement();
161 CachingReasoner cr = getWiki().getOntology().getReasoner();
162 List<Individual> individuals;
163
164 if (cached) {
165 individuals = cr.getCachedIndividuals(concept);
166 } else {
167 individuals = cr.getIndividuals(concept);
168 }
169 if (individuals != null) {
170 sentences = new ArrayList<Sentence>();
171
172 Comparator<Individual> comparator = new Comparator<Individual>() {
173 public int compare(Individual o1, Individual o2) {
174 return o1.getWord(3).compareToIgnoreCase(o2.getWord(3));
175 }
176 };
177
178 Collections.sort(individuals, comparator);
179 for (Individual ind : individuals) {
180 StatementFactory sf = getWiki().getOntology().getStatementFactory();
181 sentences.add(sf.createAssignmentSentence(ind, concept));
182 }
183 if (sentences.size() == 0) {
184 indexBar.setVisible(false);
185 sentencesColumn.add(new SolidLabel("(no individual found)", Font.ITALIC, 10));
186 } else {
187 int i = ((sentences.size()-1) / pageSize) + 1;
188 if (chosenPage > i) chosenPage = 0;
189 indexBar.setNumbers(i);
190 indexBar.setActiveButton(chosenPage);
191 updatePage();
192 }
193 } else {
194 indexBar.setVisible(false);
195 sentencesColumn.add(new SolidLabel("...", Font.ITALIC, 10));
196 }
197 }
198
199 private void updatePage() {
200 sentencesColumn.removeAll();
201
202 indexBar.setVisible(sentences.size() > pageSize);
203
204 int max = sentences.size();
205 if (max > (chosenPage + 1) * pageSize) max = (chosenPage + 1) * pageSize;
206
207 for (int i = chosenPage * pageSize; i < max; i++) {
208 Row r = new Row();
209 r.add(new SentenceComponent(sentences.get(i), IndividualsPage.this));
210 sentencesColumn.add(r);
211 }
212 }
213
214 public void actionPerformed(ActionEvent e) {
215 if (e.getSource() == indexBar) {
216 chosenPage = Integer.parseInt(e.getActionCommand()) - 1;
217 log("page", "pressed: page " + (chosenPage+1));
218 updatePage();
219 }
220 }
221
222 }
223
224 }