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;
016    
017    import java.util.Collections;
018    import java.util.List;
019    
020    import nextapp.echo2.app.Color;
021    import nextapp.echo2.app.Column;
022    import nextapp.echo2.app.Component;
023    import nextapp.echo2.app.Font;
024    import nextapp.echo2.app.Insets;
025    import nextapp.echo2.app.ResourceImageReference;
026    import nextapp.echo2.app.Row;
027    import nextapp.echo2.app.event.ActionEvent;
028    import nextapp.echo2.app.event.ActionListener;
029    import ch.uzh.ifi.attempto.acewiki.Task;
030    import ch.uzh.ifi.attempto.acewiki.Wiki;
031    import ch.uzh.ifi.attempto.acewiki.core.ontology.Individual;
032    import ch.uzh.ifi.attempto.acewiki.core.ontology.NounConcept;
033    import ch.uzh.ifi.attempto.acewiki.core.ontology.OntologyElement;
034    import ch.uzh.ifi.attempto.acewiki.core.ontology.Sentence;
035    import ch.uzh.ifi.attempto.acewiki.core.text.OntologyTextElement;
036    import ch.uzh.ifi.attempto.acewiki.gui.editor.CommentEditorWindow;
037    import ch.uzh.ifi.attempto.acewiki.gui.editor.SentenceEditorHandler;
038    import ch.uzh.ifi.attempto.acewiki.gui.page.ArticlePage;
039    import ch.uzh.ifi.attempto.acewiki.gui.page.LogicPage;
040    import ch.uzh.ifi.attempto.acewiki.gui.page.SentencePage;
041    import ch.uzh.ifi.attempto.acewiki.gui.page.WikiPage;
042    import ch.uzh.ifi.attempto.echocomp.DelayedComponent;
043    import ch.uzh.ifi.attempto.echocomp.HSpace;
044    import ch.uzh.ifi.attempto.echocomp.Label;
045    import ch.uzh.ifi.attempto.echocomp.MessageWindow;
046    import ch.uzh.ifi.attempto.echocomp.SolidLabel;
047    import ch.uzh.ifi.attempto.echocomp.VSpace;
048    import ch.uzh.ifi.attempto.preditor.text.BasicTextElement;
049    import ch.uzh.ifi.attempto.preditor.text.TextElement;
050    
051    /**
052     * This class represents a text row that consists of a drop down menu and an ACE text.
053     * 
054     * @author Tobias Kuhn
055     */
056    public class TextRow extends Column implements ActionListener {
057    
058            private static final long serialVersionUID = -540135972060005725L;
059            
060            private Sentence sentence;
061            private Wiki wiki;
062            private WikiPage hostPage;
063            
064            private Row sentenceRow = new Row();
065            private DropDownMenu dropDown;
066            private Label waitIcon = new Label(new ResourceImageReference("ch/uzh/ifi/attempto/acewiki/gui/img/wait.gif"));
067            
068            /**
069             * Creates a new text row. The host page is the page that contains the text row (which is
070             * not necessarily the owner page of the sentence).
071             * 
072             * @param sentence The sentence to be shown.
073             * @param hostPage The host page of the text row.
074             */
075            public TextRow(Sentence sentence, WikiPage hostPage) {
076                    this.sentence = sentence;
077                    this.hostPage = hostPage;
078                    this.wiki = hostPage.getWiki();
079                    update();
080            }
081            
082            private void update() {
083                    if (sentence.isInferred()) {
084                            dropDown = new DropDownMenu("light-blue", this);
085                    } else if (sentence.isReasonerParticipant() || (sentence.isQuestion() && sentence.isOWL()) ) {
086                            dropDown = new DropDownMenu("blue", this);
087                    } else {
088                            dropDown = new DropDownMenu("red", this);
089                    }
090                    if (!sentence.isIntegrated() && !sentence.isInferred()) {
091                            dropDown.addMenuEntry("Reassert");
092                            dropDown.addMenuSeparator();
093                    }
094                    if (!sentence.isInferred()) {
095                            dropDown.addMenuEntry("Edit...");
096                    }
097                    if (hostPage instanceof ArticlePage) {
098                            dropDown.addMenuEntry("Add Sentence...");
099                            dropDown.addMenuEntry("Add Comment...");
100                    }
101                    if (!sentence.isInferred()) {
102                            dropDown.addMenuEntry("Delete");
103                    }
104                    dropDown.addMenuSeparator();
105                    dropDown.addMenuEntry("Details");
106                    dropDown.addMenuEntry("Logic");
107                    
108                    Row r = new Row();
109                    Color color = Color.BLACK;
110                    boolean isRed = !sentence.isIntegrated() && !sentence.isInferred() && !sentence.isQuestion();
111                    if (isRed) {
112                            color = new Color(193, 0, 0);
113                    }
114                    for (TextElement e : sentence.getTextElements()) {
115                            if (!e.getText().matches("[.?]") && r.getComponentCount() > 0) {
116                                    r.add(new HSpace());
117                            }
118                            if (e instanceof OntologyTextElement) {
119                                    // Proper names with definite articles are handled differently:
120                                    // The "the" is not a part of the link. Probably, this should be done at a different place...
121                                    OntologyTextElement ote = (OntologyTextElement) e;
122                                    OntologyElement oe = ote.getOntologyElement();
123                                    if (oe instanceof Individual) {
124                                            Individual ind = (Individual) oe;
125                                            int wn = ote.getWordNumber();
126                                            
127                                            if (ind.hasDefiniteArticle(wn)) {
128                                                    SolidLabel l = new SolidLabel(e.getText().substring(0, 3));
129                                                    l.setForeground(color);
130                                                    r.add(l);
131                                                    r.add(new HSpace());
132                                                    r.add(new WikiLink(oe, oe.getPrettyWord(wn + 1), wiki, isRed));
133                                            } else {
134                                                    r.add(new WikiLink(((OntologyTextElement) e), wiki, isRed));
135                                            }
136                                    } else {
137                                            r.add(new WikiLink(((OntologyTextElement) e), wiki, isRed));
138                                    }
139                            } else {
140                                    SolidLabel l = new SolidLabel(e.getText());
141                                    l.setForeground(color);
142                                    r.add(l);
143                            }
144                    }
145                    
146                    removeAll();
147                    sentenceRow.removeAll();
148                    sentenceRow.add(dropDown);
149                    sentenceRow.add(new HSpace(5));
150                    sentenceRow.add(r);
151                    sentenceRow.add(new HSpace(5));
152                    sentenceRow.add(waitIcon);
153                    waitIcon.setVisible(false);
154                    sentenceRow.add(new HSpace(5));
155                    add(sentenceRow);
156                    
157                    if (sentence.isQuestion() && hostPage instanceof ArticlePage) {
158                            
159                            Column answerColumn = new Column();
160                            answerColumn.setInsets(new Insets(20, 0, 0, 0));
161                            add(answerColumn);
162                            
163                            Column cachedAnswerCol = new Column();
164                            List<OntologyElement> answer = sentence.getCachedAnswer();
165                            if (answer == null) {
166                                    cachedAnswerCol.add(new SolidLabel("...", Font.ITALIC, 10));
167                            } else if (answer.size() > 0) {
168                                    Collections.sort(answer);
169                                    for (OntologyElement oe : answer) {
170                                            Row answerRow = new Row();
171                                            if (oe instanceof NounConcept) {
172                                                    BasicTextElement a = new BasicTextElement("a");
173                                                    a.checkNeighborTextElements(new BasicTextElement(""), new BasicTextElement(oe.getWord()));
174                                                    answerRow.add(new ListItem(new SolidLabel(a.getText()), new HSpace(), new WikiLink(oe, wiki)));
175                                            } else {
176                                                    answerRow.add(new ListItem(new WikiLink(oe, wiki)));
177                                            }
178                                            cachedAnswerCol.add(answerRow);
179                                    }
180                            } else {
181                                    cachedAnswerCol.add(new SolidLabel("(no answer found)", Font.ITALIC, 10));
182                            }
183                            cachedAnswerCol.add(new VSpace(4));
184                            
185                            if (sentence.isAnswerCached()) {
186                                    
187                                    answerColumn.add(cachedAnswerCol);
188                                    
189                            } else {
190                                    waitIcon.setVisible(true);
191                                    answerColumn.add(
192                                            new DelayedComponent(cachedAnswerCol, true) {
193                                            
194                                                    private static final long serialVersionUID = 7865984138467729544L;
195            
196                                                    public Component initComponent() {
197                                                            Column column = new Column();
198                                                            List<OntologyElement> answer = sentence.getAnswer();
199                                                            if (answer == null) {
200                                                                    column.add(new SolidLabel("...", Font.ITALIC, 10));
201                                                            } else if (answer.size() > 0) {
202                                                                    Collections.sort(answer);
203                                                                    for (OntologyElement oe : answer) {
204                                                                            Row answerRow = new Row();
205                                                                            if (oe instanceof NounConcept) {
206                                                                                    BasicTextElement a = new BasicTextElement("a");
207                                                                                    a.checkNeighborTextElements(new BasicTextElement(""), new BasicTextElement(oe.getWord()));
208                                                                                    answerRow.add(new ListItem(new SolidLabel(a.getText()), new HSpace(), new WikiLink(oe, wiki)));
209                                                                            } else {
210                                                                                    answerRow.add(new ListItem(new WikiLink(oe, wiki)));
211                                                                            }
212                                                                            column.add(answerRow);
213                                                                    }
214                                                            } else {
215                                                                    column.add(new SolidLabel("(no answer found)", Font.ITALIC, 10));
216                                                            }
217                                                            column.add(new VSpace(4));
218                                                            
219                                                            return column;
220                                                    }
221                                                    
222                                                    public void finalizeAction() {
223                                                            waitIcon.setVisible(false);
224                                                    }
225                                                    
226                                            }
227                                    );
228                            }
229                            
230                    }
231            }
232    
233            public void actionPerformed(ActionEvent e) {
234                    if (e.getActionCommand().equals("Edit...")) {
235                            wiki.log("page", "dropdown: edit sentence: " + sentence.getText());
236                            ArticlePage page = ArticlePage.create(sentence.getOwner(), wiki);
237                            wiki.showPage(page);
238                            wiki.showWindow(SentenceEditorHandler.generatePreditorEditWindow(sentence, page));
239                    } else if (e.getActionCommand().equals("Add Sentence...")) {
240                            wiki.log("page", "dropdown: add sentence");
241                            wiki.showWindow(SentenceEditorHandler.generatePreditorAddWindow(sentence, (ArticlePage) hostPage));
242                    } else if (e.getActionCommand().equals("Add Comment...")) {
243                            wiki.log("page", "dropdown: add comment");
244                            wiki.showWindow(new CommentEditorWindow(sentence, (ArticlePage) hostPage, false));
245                    } else if (e.getActionCommand().equals("Delete")) {
246                            wiki.log("page", "dropdown: delete sentence: " + sentence.getText());
247                            wiki.showWindow(new MessageWindow("Delete", "Do you really want to delete this sentence?", null, this, "Yes", "No"));
248                    } else if (e.getActionCommand().equals("Reassert")) {
249                            int success = sentence.reassert();
250                            if (success == 1) {
251                                    wiki.showWindow(new MessageWindow("Conflict", "A sentence is in conflict with the current knowledge. For that reason, it cannot be added to the knowledge base.", "OK"));
252                            } else if (success == 2) {
253                                    wiki.showWindow(new MessageWindow("Error", "A sentence could not be added to the knowledge base because the knowledge base got too complex.", "OK"));
254                            }
255                            if (sentence.isIntegrated()) {
256                                    update();
257                            }
258                    } else if (e.getActionCommand().equals("Details")) {
259                            wiki.log("page", "dropdown: details sentence: " + sentence.getText());
260                            wiki.showPage(new SentencePage(wiki, sentence));
261                    } else if (e.getActionCommand().equals("Logic")) {
262                            wiki.log("page", "dropdown: logic sentence: " + sentence.getText());
263                            wiki.showPage(new LogicPage(wiki, sentence));
264                    } else if (e.getSource() instanceof MessageWindow && e.getActionCommand().equals("Yes")) {
265                            wiki.log("page", "dropdown: delete confirmed: " + sentence.getText());
266                            
267                            wiki.enqueueAsyncTask(
268                                    "Updating",
269                                    "The sentence is being removed from the knowledge base...",
270                                    new Task() {
271                                            public void run() {
272                                                    sentence.getOwner().remove(sentence);
273                                            }
274                                            public void updateGUI() {
275                                                    wiki.update();
276                                                    wiki.refresh();
277                                            }
278                                    }
279                            );
280                    }
281            }
282    
283    }