package jav.gui.token.behaviour;
import com.jidesoft.swing.StyleRange;
import jav.correctionBackend.Candidate;
import jav.correctionBackend.Token;
import jav.gui.events.MessageCenter;
import jav.gui.events.tokenDeselection.TokenDeselectionEvent;
import jav.gui.events.tokenSelection.TokenSelectionEvent;
import jav.gui.events.tokenSelection.TokenSelectionType;
import jav.gui.main.MainController;
import jav.gui.token.display.TokenVisualization;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.prefs.Preferences;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.Timer;
import org.openide.util.NbPreferences;
/**
*Copyright (c) 2012, IMPACT working group at the Centrum für Informations- und Sprachverarbeitung, University of Munich.
*All rights reserved.
*Redistribution and use in source and binary forms, with or without
*modification, are permitted provided that the following conditions are met:
*Redistributions of source code must retain the above copyright
*notice, this list of conditions and the following disclaimer.
*Redistributions in binary form must reproduce the above copyright
*notice, this list of conditions and the following disclaimer in the
*documentation and/or other materials provided with the distribution.
*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
*IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
*TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
*PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
*HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
*SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
*LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
*OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the ocr-postcorrection tool developed
* by the IMPACT working group at the Centrum für Informations- und Sprachverarbeitung, University of Munich.
* For further information and contacts visit http://ocr.cis.uni-muenchen.de/
*
* @author thorsten (thorsten.vobl@googlemail.com)
*
* default implementation of TokenVisualisation behaviour, also showcase of how
* to implement new modes
*
*/
public class TokenVisualizationDefaultMode implements TokenVisualizationMode {
private Preferences node;
private TokenVisualization lastSelectedTv = null;
private int clickDelay = 250;
private int candNum = 0;
private Timer clickTimer;
private MouseListener ml;
private KeyListener kl;
private static final HashMap<String, Color> definedTagColors = new HashMap<String, Color>() {
{
put("normalToken", Color.white);
put("correctedTrue", Color.green);
put("lexicalFalse", Color.red);
put("normalFalse", Color.orange);
}
};
public TokenVisualizationDefaultMode() {
node = NbPreferences.forModule(this.getClass());
candNum = node.getInt("candNum", 10);
ml = new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
if (e.getSource() instanceof TokenVisualization) {
final TokenVisualization tv = (TokenVisualization) e.getSource();
if (e.getClickCount() == 1) {
// single left click = selection / deselection
if (e.getButton() == MouseEvent.BUTTON1) {
clickTimer = new Timer(clickDelay, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (lastSelectedTv == null) {
lastSelectedTv = tv;
lastSelectedTv.setSelected(true);
MessageCenter.getInstance().fireTokenSelectionEvent(new TokenSelectionEvent(lastSelectedTv, tv.getTokenID(), TokenSelectionType.NORMAL));
} else {
if (lastSelectedTv.equals(tv)) {
lastSelectedTv.setSelected(false);
MessageCenter.getInstance().fireTokenDeselectionEvent(new TokenDeselectionEvent(lastSelectedTv, lastSelectedTv.getTokenID()));
lastSelectedTv = null;
// deselection event
} else {
// selecting other token while last one still selected
// MessageCenter.getInstance().fireTokenDeselectionEvent(new TokenDeselectionEvent(lastSelectedTv, tv.getToken().getIndexInDocument()));
lastSelectedTv.setSelected(false);
tv.setSelected(true);
lastSelectedTv = tv;
MessageCenter.getInstance().fireTokenSelectionEvent(new TokenSelectionEvent(lastSelectedTv, tv.getTokenID(), TokenSelectionType.NORMAL));
}
}
}
});
clickTimer.setRepeats(false);
clickTimer.start();
} // single right click == select and show popup
else if (e.getButton() == MouseEvent.BUTTON3) {
if (lastSelectedTv != null) {
// if (!lastSelectedTv.equals(tv)) {
// selecting other token while last one still selected
// MessageCenter.getInstance().fireTokenDeselectionEvent(new TokenDeselectionEvent(this, lastSelectedTv.getToken().getIndexInDocument()));
lastSelectedTv.setSelected(false);
if( lastSelectedTv.isEditing()) {
lastSelectedTv.abortTokenEditing();
}
// }
}
tv.setSelected(true);
lastSelectedTv = tv;
MessageCenter.getInstance().fireTokenSelectionEvent(new TokenSelectionEvent(lastSelectedTv, tv.getTokenID(), TokenSelectionType.NORMAL));
lastSelectedTv.startTokenEditing();
}
// double left click = correction
} else if (e.getClickCount() == 2) {
// double left click
if (e.getButton() == MouseEvent.BUTTON1) {
clickTimer.stop();
if (lastSelectedTv != null) {
if (!lastSelectedTv.equals(tv)) {
// selecting other token while last one still selected
// MessageCenter.getInstance().fireTokenDeselectionEvent(new TokenDeselectionEvent(this, lastSelectedTv.getToken().getIndexInDocument()));
lastSelectedTv.setSelected(false);
}
}
tv.setSelected(true);
lastSelectedTv = tv;
MessageCenter.getInstance().fireTokenSelectionEvent(new TokenSelectionEvent(lastSelectedTv, tv.getTokenID(), TokenSelectionType.NORMAL));
lastSelectedTv.startTokenEditing();
}
}
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
};
kl = new KeyListener() {
@Override
public void keyTyped(KeyEvent ke) {
}
@Override
public void keyPressed(KeyEvent ke) {
if (lastSelectedTv != null) {
if (ke.getKeyCode() == KeyEvent.VK_ENTER & !lastSelectedTv.isEditing()) {
lastSelectedTv.startTokenEditing();
// // if delete, check if prev and next token are spaces, if the case delete one of them to not produce sequent spaces
} else if (ke.getKeyCode() == KeyEvent.VK_DELETE) {
int position = lastSelectedTv.getTokenID();
MainController.findInstance().deleteToken(position);
}
}
}
@Override
public void keyReleased(KeyEvent ke) {
}
};
}
@Override
public void unSelect() {
if (this.lastSelectedTv != null) {
this.lastSelectedTv.setSelected(false);
this.lastSelectedTv = null;
}
}
@Override
public void setSelectedTokenVisualization(TokenVisualization tv) {
this.lastSelectedTv = tv;
this.setTokenVisualizationStyle(this.lastSelectedTv);
}
@Override
public void setCorrected(TokenVisualization tv, boolean b) {
Color fontColor = this.getUnselectedColor();
if (tv.isSelected()) {
fontColor = this.getSelectedColor();
}
Color tagColor;
if (b) {
tagColor = definedTagColors.get("correctedTrue");
} else {
tagColor = definedTagColors.get("normalToken");
}
tv.getTokenTextLabel().clearStyleRanges();
tv.getTokenTextLabel().addStyleRange(new StyleRange(0, -1, Font.PLAIN, fontColor, StyleRange.STYLE_WAVED, tagColor));
}
@Override
public TokenVisualization getSelectedTokenVisualization() {
return this.lastSelectedTv;
}
@Override
public MouseListener getMouseListener() {
return ml;
}
@Override
public Color getSelectedColor() {
return Color.red;
}
@Override
public Color getMultiSelectedColor() {
return Color.orange;
}
@Override
public Color getUnselectedColor() {
return Color.black;
}
@Override
public void setTokenVisualizationStyle(TokenVisualization tv) {
Color fontColor = this.getUnselectedColor();
if (tv.isSelected()) {
fontColor = this.getSelectedColor();
}
if (tv.isMultiSelected()) {
fontColor = this.getMultiSelectedColor();
}
tv.getTokenTextLabel().clearStyleRanges();
Token token = MainController.findInstance().getDocument().getTokenByID(tv.getTokenID());
if (token.isCorrected() && token.isNormal()) {
Color tagColor = definedTagColors.get("correctedTrue");
tv.getTokenTextLabel().addStyleRange(new StyleRange(0, -1, Font.PLAIN, fontColor, StyleRange.STYLE_WAVED, tagColor));
} else if (token.isSuspicious() && token.isNormal()) {
Color tagColor = definedTagColors.get("lexicalFalse");
tv.getTokenTextLabel().addStyleRange(new StyleRange(0, -1, Font.PLAIN, fontColor, StyleRange.STYLE_WAVED, tagColor));
// } else if (!tv.getToken().isNormal()) {
// Color tagColor = definedTagColors.get("normalFalse");
// tv.getTokenTextLabel().addStyleRange(new StyleRange(0, -1, Font.PLAIN, fontColor, StyleRange.STYLE_WAVED, tagColor));
} else {
Color tagColor = definedTagColors.get("normalToken");
tv.getTokenTextLabel().addStyleRange(new StyleRange(0, -1, Font.PLAIN, fontColor, StyleRange.STYLE_WAVED, tagColor));
}
}
@Override
public void setTokenVisualizationStyle(TokenVisualization tv, Token token) {
Color fontColor = this.getUnselectedColor();
if (tv.isSelected()) {
fontColor = this.getSelectedColor();
}
if (tv.isMultiSelected()) {
fontColor = this.getMultiSelectedColor();
}
tv.getTokenTextLabel().clearStyleRanges();
if (token.isCorrected() && token.isNormal()) {
Color tagColor = definedTagColors.get("correctedTrue");
tv.getTokenTextLabel().addStyleRange(new StyleRange(0, -1, Font.PLAIN, fontColor, StyleRange.STYLE_WAVED, tagColor));
} else if (token.isSuspicious() && token.isNormal()) {
Color tagColor = definedTagColors.get("lexicalFalse");
tv.getTokenTextLabel().addStyleRange(new StyleRange(0, -1, Font.PLAIN, fontColor, StyleRange.STYLE_WAVED, tagColor));
// } else if (!tv.getToken().isNormal()) {
// Color tagColor = definedTagColors.get("normalFalse");
// tv.getTokenTextLabel().addStyleRange(new StyleRange(0, -1, Font.PLAIN, fontColor, StyleRange.STYLE_WAVED, tagColor));
} else {
Color tagColor = definedTagColors.get("normalToken");
tv.getTokenTextLabel().addStyleRange(new StyleRange(0, -1, Font.PLAIN, fontColor, StyleRange.STYLE_WAVED, tagColor));
}
}
@Override
public KeyListener getKeyListener() {
return kl;
}
public JPopupMenu getPopupMenu() {
JPopupMenu menu = new JPopupMenu();
ActionListener editListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
lastSelectedTv.startTokenEditing();
lastSelectedTv.repaint();
lastSelectedTv.revalidate();
}
};
JMenuItem editItem = new JMenuItem(java.util.ResourceBundle.getBundle("jav/gui/token/display/Bundle").getString("edit"));
editItem.addActionListener(editListener);
menu.add(editItem);
menu.addSeparator();
JMenuItem cor = new JMenuItem(java.util.ResourceBundle.getBundle("jav/gui/token/display/Bundle").getString("setcorr"));
cor.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MainController.findInstance().setCorrected(lastSelectedTv.getTokenID(), true);
}
});
menu.add(cor);
menu.addSeparator();
ActionListener itemActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JMenuItem jm = (JMenuItem) e.getSource();
MainController.findInstance().correctTokenByString(lastSelectedTv.getTokenID(), jm.getText());
MainController.findInstance().addToLog(MainController.findInstance().getLastFocusedTCName() + " # correct # candidate # " + lastSelectedTv.getTokenTextLabelText() + " # " + jm.getText());
}
};
// Create and add a menu item
//CandidateSet cs = MainController.findInstance().getCorrectionSystem().computeCandidates(lastSelectedTv.getToken());
//Iterator<Candidate> candIterator = cs.candIterator();
Iterator<Candidate> candIterator = MainController.findInstance().getDocument().candidateIterator(lastSelectedTv.getTokenID());
if (candIterator.hasNext()) {
int counter = 0;
while (counter < candNum && candIterator.hasNext()) {
counter++;
Candidate cand = candIterator.next();
JMenuItem item = new JMenuItem(cand.getSuggestion());
// item.setToolTipText(java.util.ResourceBundle.getBundle("jav/gui/token/display/Bundle").getString("lev_dist") + cand.getDlev()
// + java.util.ResourceBundle.getBundle("jav/gui/token/display/Bundle").getString("cand_frq") + cand.getFrequency()
// + "</html>");
item.addActionListener(itemActionListener);
menu.add(item);
}
}
//////////////// add menu entry for merge to right
menu.addSeparator();
ActionListener mergeRightActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MainController.findInstance().mergeRightward(lastSelectedTv.getTokenID());
MainController.findInstance().addToLog(MainController.findInstance().getLastFocusedTCName() + " # merge # " + " # " + lastSelectedTv.getTokenTextLabelText() + " # " + lastSelectedTv.getTokenTextLabelText());
}
};
JMenuItem mergeRightItem = new JMenuItem(java.util.ResourceBundle.getBundle("jav/gui/token/display/Bundle").getString("mergeR"));
mergeRightItem.addActionListener(mergeRightActionListener);
menu.add(mergeRightItem);
//////////// add menu entry for hyphenation
// ActionListener mergeHyphenationActionListener = new ActionListener() {
//
// @Override
// public void actionPerformed(ActionEvent e) {
// JMenuItem jm = (JMenuItem) e.getSource();
// // todo check for success of merge
// lastSelectedTv.getToken().mergeHyphenation();
// MessageCenter.getInstance().fireTokenStatusEvent(new TokenStatusEvent(lastSelectedTv.getToken(), TokenStatusType.MERGED_RIGHT));
// }
// };
return menu;
}
}