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.editor; 016 017 import java.util.ArrayList; 018 import java.util.List; 019 020 import nextapp.echo2.app.event.ActionEvent; 021 import nextapp.echo2.app.event.ActionListener; 022 import ch.uzh.ifi.attempto.acewiki.Task; 023 import ch.uzh.ifi.attempto.acewiki.Wiki; 024 import ch.uzh.ifi.attempto.acewiki.core.ontology.OntologyElement; 025 import ch.uzh.ifi.attempto.acewiki.core.ontology.Sentence; 026 import ch.uzh.ifi.attempto.acewiki.core.ontology.Statement; 027 import ch.uzh.ifi.attempto.acewiki.gui.page.ArticlePage; 028 import ch.uzh.ifi.attempto.echocomp.MessageWindow; 029 import ch.uzh.ifi.attempto.preditor.PreditorWindow; 030 import ch.uzh.ifi.attempto.preditor.text.TextContainer; 031 import ch.uzh.ifi.attempto.preditor.text.TextElement; 032 033 /** 034 * This class manages the predictive editor. It creates the editor window and handles its 035 * responses. 036 * 037 * @author Tobias Kuhn 038 */ 039 public class SentenceEditorHandler implements ActionListener { 040 041 private static final long serialVersionUID = -2083910385095284075L; 042 043 private PreditorWindow editorWindow; 044 private MessageWindow messageWindow; 045 private ArticlePage page; 046 private Wiki wiki; 047 private boolean edit; 048 private Statement statement; 049 private List<Sentence> newSentences = new ArrayList<Sentence>(); 050 private int checked = 0; 051 052 private SentenceEditorHandler(Statement statement, ArticlePage page, boolean edit) { 053 this.page = page; 054 this.wiki = page.getWiki(); 055 this.edit = edit; 056 this.statement = statement; 057 AceWikiMenuCreator menuCreator = new AceWikiMenuCreator(wiki, page.getOntologyElement(), this); 058 editorWindow = new PreditorWindow("Sentence Editor", wiki.getGrammar(), menuCreator); 059 editorWindow.addActionListener(this); 060 061 if (edit) { 062 String t = ((Sentence) statement).getPrettyText(); 063 // remove the last element (i.e. the period '.' or question mark '?'): 064 editorWindow.addText(t.substring(0, t.length()-1) + " "); 065 } 066 } 067 068 /** 069 * Generates a new preditive editor (short "preditor") window to create a new sentence. 070 * 071 * @param followingStatement The statement in front of which the new sentences should be added, 072 * or null if the sentences should be added to the end of the article. 073 * @param page The host page into which the sentence should be added. 074 * @return A new preditor window. 075 */ 076 public static PreditorWindow generatePreditorAddWindow(Statement followingStatement, ArticlePage page) { 077 SentenceEditorHandler h = new SentenceEditorHandler(followingStatement, page, false); 078 return h.getPreditorWindow(); 079 } 080 081 /** 082 * Generates a new preditive editor (short "preditor") window to create a new sentence. 083 * 084 * @param sentence The sentence that should be edited. 085 * @param page The host page which contains the sentence to be edited. 086 * @return A new preditor window. 087 */ 088 public static PreditorWindow generatePreditorEditWindow(Sentence sentence, ArticlePage page) { 089 SentenceEditorHandler h = new SentenceEditorHandler(sentence, page, true); 090 return h.getPreditorWindow(); 091 } 092 093 private PreditorWindow getPreditorWindow() { 094 return editorWindow; 095 } 096 097 public void actionPerformed(ActionEvent e) { 098 if (e.getSource() == editorWindow && e.getActionCommand().equals("OK")) { 099 TextContainer textContainer = editorWindow.getTextContainer(); 100 101 ArrayList<TextElement> finalElements = editorWindow.getPossibleNextTokens(".", "?"); 102 if (!finalElements.isEmpty()) textContainer.addElement(finalElements.get(0)); 103 104 ArrayList<TextElement> l = textContainer.getTextElements(); 105 if (l.isEmpty() || l.get(l.size() - 1).getText().matches("[.?]")) { 106 newSentences = Sentence.generateSentences(textContainer, page.getOntologyElement()); 107 checkSentence(); 108 } else { 109 wiki.log("edit", "error: unfinished sentences"); 110 MessageWindow mw = new MessageWindow("Error", "There are unfinished sentences.", editorWindow, "OK"); 111 page.getWiki().showWindow(mw); 112 } 113 } else if (e.getSource() == editorWindow && e.getActionCommand().equals("Cancel")) { 114 editorWindow.setVisible(false); 115 editorWindow.dispose(); 116 } else if (e.getSource() == messageWindow && e.getActionCommand().equals("a ...")) { 117 checked++; 118 checkSentence(); 119 } else if (e.getSource() == messageWindow && e.getActionCommand().equals("every ...")) { 120 String text = newSentences.get(checked).getText(); 121 text = text.replaceFirst("^(A|a)n? ", "Every "); 122 newSentences.remove(checked); 123 newSentences.add(checked, new Sentence(text, page.getOntologyElement())); 124 checked++; 125 checkSentence(); 126 } else if (e.getSource() == messageWindow && e.getActionCommand().equals("Close")) { 127 checked = 0; 128 } else if (e.getSource() instanceof TextElement) { 129 editorWindow.addTextElement((TextElement) e.getSource()); 130 } 131 } 132 133 private void checkSentence() { 134 if (checked >= newSentences.size()) { 135 assertSentences(); 136 } else { 137 List<TextElement> t = newSentences.get(checked).getTextElements(); 138 String t0 = t.get(0).getText(); 139 String t1 = t.get(1).getText(); 140 String l = t.get(t.size()-1).getText(); 141 if (t0.matches("(A|a)n?") && !t1.matches(".* of") && l.equals(".")) { 142 String s = t.get(1).getText(); 143 messageWindow = new MessageWindow( 144 "Warning", 145 "Your sentence \"a " + s + " ...\" is interpreted as \"there is a " + s + " that ...\". " + 146 "Do you want to say \"every " + s + " ...\"?", 147 editorWindow, 148 this, 149 "a ...", "every ..." 150 ); 151 wiki.showWindow(messageWindow); 152 } else { 153 checked++; 154 checkSentence(); 155 } 156 } 157 } 158 159 private void assertSentences() { 160 final TextContainer textContainer = editorWindow.getTextContainer(); 161 final OntologyElement el = page.getOntologyElement(); 162 163 Task task = new Task() { 164 165 int success; 166 167 public void run() { 168 if (edit) { 169 wiki.log("edit", "sentence updated: " + textContainer.getText()); 170 success = el.edit(statement, new ArrayList<Statement>(newSentences)); 171 } else { 172 wiki.log("edit", "sentence created: " + textContainer.getText()); 173 success = el.add(statement, new ArrayList<Statement>(newSentences)); 174 } 175 } 176 177 public void updateGUI() { 178 page.update(); 179 if (success == 1) { 180 wiki.showWindow( 181 new MessageWindow( 182 "Conflict", 183 "A sentence is in conflict with the current knowledge. For that reason, " + 184 "it cannot be added to the knowledge base.", 185 "OK" 186 ) 187 ); 188 } else if (success == 2) { 189 wiki.showWindow( 190 new MessageWindow( 191 "Error", 192 "A sentence could not be added to the knowledge base because the knowledge " + 193 "base got too complex.", 194 "OK" 195 ) 196 ); 197 } 198 if (page != null) { 199 page.update(); 200 page.getWiki().update(); 201 } 202 } 203 204 }; 205 206 if (edit) { 207 wiki.enqueueAsyncTask("Updating", "The knowledge base is being updated...", task); 208 } else { 209 wiki.enqueueAsyncTask("Updating", "The sentence is being added to the knowledge base...", task); 210 } 211 212 editorWindow.setVisible(false); 213 } 214 215 }