// This file is part of AceWiki.
// Copyright 2008-2013, AceWiki developers.
//
// AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
// Lesser General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
// even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
// not, see http://www.gnu.org/licenses/.
package ch.uzh.ifi.attempto.aceeditor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nextapp.echo.app.Alignment;
import nextapp.echo.app.Button;
import nextapp.echo.app.Color;
import nextapp.echo.app.Column;
import nextapp.echo.app.Extent;
import nextapp.echo.app.Font;
import nextapp.echo.app.Insets;
import nextapp.echo.app.Row;
import nextapp.echo.app.event.ActionEvent;
import nextapp.echo.app.event.ActionListener;
import nextapp.echo.app.layout.RowLayoutData;
import ch.uzh.ifi.attempto.ape.ACEParser;
import ch.uzh.ifi.attempto.ape.ACEParserResult;
import ch.uzh.ifi.attempto.ape.Lexicon;
import ch.uzh.ifi.attempto.ape.Message;
import ch.uzh.ifi.attempto.ape.OutputType;
import ch.uzh.ifi.attempto.echocomp.SquareButton;
import ch.uzh.ifi.attempto.echocomp.Style;
import ch.uzh.ifi.attempto.base.APE;
/**
* This class represents a text entry of the ACE Editor. Such a text entry consists of an ACE text
* or a comment. In the case it is an ACE text, the text entry also contains result items that show
* the parsing results. These parsing results can be hidden (collapsed) or shown (expanded).
* Comments start with "# ".
*
* @author Tobias Kuhn
*/
class TextEntry extends Column implements ActionListener {
private static final long serialVersionUID = -1976178070379593477L;
private static final String imgpath = "ch/uzh/ifi/attempto/echocomp/style/";
private final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(this.getClass());
private ACEParser aceParser;
private Map<String,ResultItem> resultItems = new HashMap<String,ResultItem>();
private boolean selected = false;
private boolean expanded = true;
private boolean error = false;
private boolean comment = false;
private ACEEditor owner;
private String text;
private Column resultsColumn;
private Button sentenceButton;
private SquareButton expandButton = new SquareButton("right", this);
/**
* Creates a new text entry with collapsed result items.
*
* @param text The ACE text or comment.
* @param owner The ACE Editor object.
*/
public TextEntry(String text, ACEEditor owner) {
this(text, owner, null, false);
}
/**
* Creates a new text entry.
*
* @param text The ACE text or comment.
* @param owner The ACE Editor object.
* @param expanded true if the result items should be expanded, false if they should be
* collapsed.
*/
public TextEntry(String text, ACEEditor owner, boolean expanded) {
this(text, owner, null, expanded);
}
/**
* Creates a new text entry with the results items according to the given template.
*
* @param text The ACE text or comment.
* @param owner The ACE Editor object.
* @param resultItemsTemplate The template according to which the result items are generated.
* @param expanded true if the result items should be expanded, false if they should be
* collapsed.
*/
private TextEntry(String text, ACEEditor owner, Map<String,ResultItem> resultItemsTemplate,
boolean expanded) {
this.owner = owner;
this.expanded = expanded;
if (text == null || text.matches("\\s*")) {
this.text = null;
} else {
this.text = text.replaceAll("\\s+", " ");
}
aceParser = APE.getParser();
Row sentenceRow = new Row();
sentenceRow.setInsets(new Insets(0, 0, 5, 0));
RowLayoutData layout = new RowLayoutData();
layout.setAlignment(new Alignment(Alignment.LEFT, Alignment.TOP));
expandButton.setLayoutData(layout);
sentenceRow.add(expandButton);
sentenceButton = new Button();
sentenceButton.setFont(new Font(Style.fontTypeface, Font.PLAIN, new Extent(13)));
sentenceButton.setInsets(new Insets(4, 1, 4, 2));
sentenceButton.setRolloverEnabled(true);
sentenceButton.addActionListener(this);
sentenceButton.setLayoutData(layout);
sentenceRow.add(sentenceButton);
add(sentenceRow);
resultsColumn = new Column();
resultsColumn.setInsets(new Insets(25, 5, 5, 5));
if (text != null) {
List<ResultItem> l = new ArrayList<ResultItem>();
l.add(createResultItem(ResultItem.PARAPHRASE, resultItemsTemplate));
l.add(createResultItem(ResultItem.SENTENCES, resultItemsTemplate));
l.add(createResultItem(ResultItem.TOKENS, resultItemsTemplate));
l.add(createResultItem(ResultItem.SYNTAX_LIST, resultItemsTemplate));
l.add(createResultItem(ResultItem.SYNTAX_TREE, resultItemsTemplate));
l.add(createResultItem(ResultItem.SYNTAX_BOXES, resultItemsTemplate));
l.add(createResultItem(ResultItem.DRS_PROLOG, resultItemsTemplate));
l.add(createResultItem(ResultItem.DRS_PRETTY, resultItemsTemplate));
l.add(createResultItem(ResultItem.DRS_XML, resultItemsTemplate));
l.add(createResultItem(ResultItem.FOL, resultItemsTemplate));
l.add(createResultItem(ResultItem.PNF, resultItemsTemplate));
l.add(createResultItem(ResultItem.OWL_FSS, resultItemsTemplate));
l.add(createResultItem(ResultItem.OWL_XML, resultItemsTemplate));
for (ResultItem ri : l) {
resultItems.put(ri.getType(), ri);
resultsColumn.add(ri);
}
if (expanded) {
add(resultsColumn);
}
}
update();
}
/**
* Returns the ACE text or comment (starting with "# ") of this text entry.
*
* @return The ACE text or comment.
*/
public String getText() {
return text;
}
/**
* Sets the ACE text or comment (starting with "# ") of this text entry.
*
* @param text The new ACE text or comment.
*/
public void setText(String text) {
if (text == null || text.matches("\\s*")) {
this.text = null;
} else {
this.text = text.replaceAll("\\s+", " ");
}
update();
}
/**
* Sets the selection status of this text entry.
*
* @param selected true for marking this text entry as selected, false to mark it as
* unselected.
*/
public void setSelected(boolean selected) {
this.selected = selected;
if (comment) {
sentenceButton.setFont(new Font(Style.fontTypeface, Font.ITALIC, new Extent(13)));
} else {
sentenceButton.setFont(new Font(Style.fontTypeface, Font.PLAIN, new Extent(13)));
}
if (selected) {
sentenceButton.setBackground(Style.mediumBackground);
sentenceButton.setRolloverBackground(Style.mediumBackground);
if (error) {
sentenceButton.setForeground(Color.RED);
sentenceButton.setRolloverForeground(Color.RED);
} else if (comment) {
sentenceButton.setForeground(new Color(240, 240, 240));
sentenceButton.setRolloverForeground(new Color(240, 240, 240));
} else {
sentenceButton.setForeground(Color.WHITE);
sentenceButton.setRolloverForeground(Color.WHITE);
}
} else {
sentenceButton.setBackground(Color.WHITE);
sentenceButton.setRolloverBackground(Style.lightBackground);
if (error) {
sentenceButton.setForeground(Color.RED);
sentenceButton.setRolloverForeground(Color.RED);
} else if (comment) {
sentenceButton.setForeground(Color.DARKGRAY);
sentenceButton.setRolloverForeground(Color.DARKGRAY);
} else {
sentenceButton.setForeground(Color.BLACK);
sentenceButton.setRolloverForeground(Color.BLACK);
}
}
}
/**
* Sets the visibility status of a certain result item of this text entry.
*
* @param resultItemType The type of the result item.
* @param visible true if the result item should be visible, or false if it should be hidden.
*/
public void setResultItemVisible(String resultItemType, boolean visible) {
ResultItem ri = resultItems.get(resultItemType);
if (ri != null) {
ri.setVisible(visible);
}
}
/**
* Returns true if the given result item is visible.
*
* @param resultItemType The type of the result item.
* @return true if the given result item is visible.
*/
public boolean isResultItemVisible(String resultItemType) {
return resultItems.get(resultItemType).isVisible();
}
/**
* Returns true if this text entry contains an empty text.
*
* @return true if this text entry is empty.
*/
public boolean isEmpty() {
return text == null;
}
/**
* Returns true if the result items of this text entry are expanded.
*
* @return true if this text entry is expanded.
*/
public boolean isExpanded() {
return expanded;
}
/**
* Returns true if the text of this text entry cannot be parsed by the ACE parser.
*
* @return true if this text entry contains a malformed ACE text.
*/
public boolean hasError() {
return error;
}
/**
* Returns true if this text entry contains a comment and not an ACE text.
*
* @return true if this text entry contains a comment.
*/
public boolean isComment() {
return comment;
}
/**
* Expands or collapses the result items of this text entry.
*
* @param expanded true to expand the text entry, or false to collapse it.
*/
public void setExpanded(boolean expanded) {
if (this.expanded == expanded || text == null || comment) {
return;
}
this.expanded = expanded;
if (expanded) {
expandButton.setIcon(Style.getImage(imgpath + "down.png"));
add(resultsColumn);
} else {
expandButton.setIcon(Style.getImage(imgpath + "right.png"));
remove(resultsColumn);
}
owner.entryChanged(this);
}
/**
* Copies this text entry.
*
* @return A copy of this text entry.
*/
public TextEntry copy() {
TextEntry copy = new TextEntry(text, owner, resultItems, expanded);
copy.selected = selected;
return copy;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == expandButton) {
if (!comment) {
if (text == null) {
owner.actionPerformed(new ActionEvent(this, "Add..."));
} else {
if (expanded) {
setExpanded(false);
} else {
setExpanded(true);
}
}
}
owner.select(this);
} else if (e.getSource() == sentenceButton) {
owner.select(this);
}
}
private ResultItem createResultItem(String name, Map<String,ResultItem> template) {
if (template == null) {
return new ResultItem(name);
} else {
return template.get(name).copy();
}
}
private void update() {
if (text == null) {
expandButton.setIconName("plus");
sentenceButton.setHeight(new Extent(17));
} else if (text.startsWith("# ")) {
expandButton.setIconName("diamond");
sentenceButton.setText(text.substring(2));
comment = true;
} else {
if (isExpanded()) {
expandButton.setIconName("down");
} else {
expandButton.setIconName("right");
}
sentenceButton.setText(text);
aceParser.setURI("http://attempto.ifi.uzh.ch/aceeditor/default");
Lexicon lexicon;
if (owner.isParseWithClexEnabled()) {
aceParser.setClexEnabled(true);
lexicon = null;
} else {
aceParser.setClexEnabled(false);
lexicon = owner.getLexiconHandler().getLexicon();
}
// TODO: submit only the part of the lexicon that is needed.
ACEParserResult parserResult = aceParser.getMultiOutput(text, lexicon,
OutputType.PARAPHRASE,
OutputType.SENTENCES,
OutputType.TOKENS,
OutputType.SYNTAX,
OutputType.SYNTAXPP,
OutputType.DRS,
OutputType.DRSPP,
OutputType.DRSXML,
OutputType.FOL,
OutputType.PNF,
OutputType.OWLFSSPP,
OutputType.OWLXML
);
for (ResultItem ri : resultItems.values()) {
ri.setContent(parserResult);
}
for (Message m : parserResult.getMessageContainer().getErrorMessages()) {
if (!m.getType().equals("owl")) {
log.warn(m.toString());
}
}
error = parserResult.get(OutputType.DRS).equals("drs([], [])");
}
setSelected(selected);
}
}