/* * JOrtho * * Copyright (C) 2005-2008 by i-net software * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * Created on 25.02.2008 */ package com.inet.jortho; import java.awt.Component; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import java.util.Locale; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import javax.swing.text.BadLocationException; import javax.swing.text.Caret; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.text.Utilities; /** * Is used from CheckerMenu and CheckerPopup to handle the user events. * @author Volker Berlin */ public class CheckerListener implements PopupMenuListener, LanguageChangeListener { private Dictionary dictionary; private Locale locale; private final JComponent menu; private final SpellCheckerOptions options; CheckerListener(final JComponent menu, final SpellCheckerOptions options) { this.menu = menu; this.options = options == null ? SpellChecker.getOptions() : options; SpellChecker.addLanguageChangeLister(this); dictionary = SpellChecker.getCurrentDictionary(); locale = SpellChecker.getCurrentLocale(); } public void languageChanged(final LanguageChangeEvent ev) { dictionary = SpellChecker.getCurrentDictionary(); locale = SpellChecker.getCurrentLocale(); } public void popupMenuCanceled(final PopupMenuEvent e) { /* empty */ } public void popupMenuWillBecomeInvisible(final PopupMenuEvent e) { /* empty */ } public void popupMenuWillBecomeVisible(final PopupMenuEvent ev) { if (SpellChecker.getCurrentDictionary() == null) { menu.setEnabled(false); return; } final JPopupMenu popup = (JPopupMenu) ev.getSource(); final Component invoker = popup.getInvoker(); if (invoker instanceof JTextComponent) { final JTextComponent jText = (JTextComponent) invoker; if (!jText.isEditable()) { // Suggestions only for editable text components menu.setEnabled(false); return; } final Caret caret = jText.getCaret(); int offs = Math.min(caret.getDot(), caret.getMark()); final Point p = jText.getMousePosition(); if (p != null) { // use position from mouse click and not from editor cursor position offs = jText.viewToModel(p); } try { final Document doc = jText.getDocument(); if (offs > 0 && (offs >= doc.getLength() || Character.isWhitespace(doc.getText(offs, 1).charAt(0)))) { // if the next character is a white space then use the word on the left site offs--; } if (offs < 0) { // occur if there nothing under the mouse pointer menu.setEnabled(false); return; } // get the word from current position final int begOffs = Utilities.getWordStart(jText, offs); final int endOffs = Utilities.getWordEnd(jText, offs); final String word = jText.getText(begOffs, endOffs - begOffs); //find the first invalid word from current position final Tokenizer tokenizer = new Tokenizer(jText, dictionary, locale, offs, options); String invalidWord; do { invalidWord = tokenizer.nextInvalidWord(); } while (tokenizer.getWordOffset() < begOffs); menu.removeAll(); if (!word.equals(invalidWord)) { // the current word is not invalid menu.setEnabled(false); return; } if (dictionary == null) { // without dictionary it is disabled menu.setEnabled(false); return; } final List<Suggestion> list = dictionary.searchSuggestions(word); //Disable then menu item if there are no suggestions menu.setEnabled(list.size() > 0); final boolean needCapitalization = tokenizer.isFirstWordInSentence() && Utils.isFirstCapitalized(word); for (int i = 0; i < list.size() && i < options.getSuggestionsLimitMenu(); i++) { final Suggestion sugestion = list.get(i); String sugestionWord = sugestion.getWord(); if (needCapitalization) { sugestionWord = Utils.getCapitalized(sugestionWord); } final JMenuItem item = new JMenuItem(sugestionWord); menu.add(item); final String newWord = sugestionWord; item.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { jText.setSelectionStart(begOffs); jText.setSelectionEnd(endOffs); jText.replaceSelection(newWord); } }); } final UserDictionaryProvider provider = SpellChecker.getUserDictionaryProvider(); if (provider == null) { return; } final JMenuItem addToDic = new JMenuItem(Utils.getResource("addToDictionary")); addToDic.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final UserDictionaryProvider provider = SpellChecker.getUserDictionaryProvider(); if (provider != null) { provider.addWord(word); } dictionary.add(word); dictionary.trimToSize(); AutoSpellChecker.refresh(jText); } }); if (list.size() > 0) { if (menu instanceof JMenu) { ((JMenu) menu).addSeparator(); } else if (menu instanceof JPopupMenu) { ((JPopupMenu) menu).addSeparator(); } } menu.add(addToDic); menu.setEnabled(true); } catch (final BadLocationException ex) { ex.printStackTrace(); } } } }