{
/**
*
*/
private static final long serialVersionUID = 1L;
Node() {
super(1);
}
int save(final DictionaryFactory factory) {
int idx;
final int start = idx = factory.size;
//reserve the needed memory
final int newSize = factory.size + size() * 3 + 1;
factory.checkSize(newSize);
factory.size = newSize;
for (int i = 0; i < size(); i++) {
final NodeEntry entry = get(i);
factory.tree[idx++] = entry.c;
final Node nextNode = entry.nextNode;
int offset = 0;
if (nextNode != null) {
offset = nextNode.save(factory);
}
if (entry.isWord) {
offset |= 0x80000000;
}
factory.tree[idx++] = (char) (offset >> 16);
factory.tree[idx++] = (char) (offset);
}
factory.tree[idx] = DictionaryBase.LAST_CHAR;
return start;
}
NodeEntry searchCharOrAdd(final char c) {
for (int i = 0; i < size(); i++) {
NodeEntry entry = get(i);
if (entry.c < c) {
continue;
}
if (entry.c == c) {
return entry;
}
entry = new NodeEntry(c);
add(i, entry);
trimToSize(); //reduce the memory consume, there is a very large count of this Nodes.
return entry;
}
final NodeEntry entry = new NodeEntry(c);
add(entry);
trimToSize(); //reduce the memory consume, there is a very large count of this Nodes.
return entry;
}
}
/**
* Descript a single charchter in the Dictionary tree.
*/
private final static class NodeEntry {
final char c;
boolean isWord;
Node nextNode;
NodeEntry(final char c) {
this.c = c;
}
/**
* Create a new Node and set it as nextNode
* @return the nextNode
*/
Node createNewNode() {
return nextNode = new Node();
}
}
private final Node root = new Node();
private int size;
private char[] tree;
/**
* Empty Constructor.
*/
public DictionaryFactory() {
/* empty */
}
/**
* Add a word to the tree. If it already exist then it has no effect.
* @param word the new word.
*/
public void add(final String word) {
Node node = root;
for (int i = 0; i < word.length(); i++) {
final char c = word.charAt(i);
final NodeEntry entry = node.searchCharOrAdd(c);
if (i == word.length() - 1) {
entry.isWord = true;
return;
}
final Node nextNode = entry.nextNode;
if (nextNode == null) {
node = entry.createNewNode();
}
else {
node = nextNode;
}
}
}
/**
* Check the size of the array and resize it if needed.
* @param newSize the requied size
*/
final void checkSize(final int newSize) {
if (newSize > tree.length) {
final char[] puffer = new char[Math.max(newSize, 2 * tree.length)];
System.arraycopy(tree, 0, puffer, 0, size);
tree = puffer;
}
}
/**
* Create from the data in this factory a Dictionary object. If there
* are no word added then the Dictionary is empty. The Dictionary need fewer memory as the DictionaryFactory.
* @return a Dictionary object.
*/
public Dictionary create() {
tree = new char[10000];
root.save(this);
//shrink the array
final char[] temp = new char[size];
System.arraycopy(tree, 0, temp, 0, size);
tree = temp;
return new Dictionary(tree);
}
/**
* Load the directory from plain a list of words. The words must be delimmited with newlines. This method can be
* called multiple times.
*
* @param stream
* a InputStream with words
* @param charsetName
* the name of a codepage for example "UTF8" or "Cp1252"
* @throws IOException
* If an I/O error occurs.
* @throws NullPointerException
* If stream or charsetName is null.
*/
public void loadPlainWordList(final InputStream stream, final String charsetName) throws IOException {
final Reader reader = new InputStreamReader(stream, charsetName);
loadPlainWordList(reader);
}
/**
* Load the directory from plain a list of words. The words must be delimmited with newlines. This method can be
* called multiple times.
*
* @param reader
* a Reader with words
* @throws IOException
* If an I/O error occurs.
* @throws NullPointerException
* If reader is null.
*/
public void loadPlainWordList(final Reader reader) throws IOException {
final BufferedReader input = new BufferedReader(reader);
String word = input.readLine();
while (word != null) {
if (word.length() > 1) {
add(word);
}
word = input.readLine();
}
}
/**
* Load the directory from a compressed list of words with UTF8 encoding. The words must be delimmited with
* newlines. This method can be called multiple times.
*
* @param filename
* the name of the file
* @throws IOException
* If an I/O error occurs.
* @throws NullPointerException
* If filename is null.
*/
public void loadWordList(final URL filename) throws IOException {
final URLConnection conn = filename.openConnection();
conn.setReadTimeout(5000);
InputStream input = conn.getInputStream();
input = new InflaterInputStream(input);
input = new BufferedInputStream(input);
loadPlainWordList(input, "UTF8");
}
}
freeplane-1.3.15/JOrtho_0.4_freeplane/src/com/inet/jortho/FileUserDictionary.java 100664 0 0 6336 12465442703 24741 0 ustar 0 0 /*
* 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 23.12.2007
*/
package com.inet.jortho;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Locale;
/**
* This is a reference implementation of the interface {@link UserDictionaryProvider}.
* It save the user dictionaries on the local disk as text files.
* @author Volker Berlin
*/
public class FileUserDictionary implements UserDictionaryProvider {
private File file;
private final String fileBase;
/**
* Create a FileUserDictionary with the dictionaries in the root of the current
* application.
*/
public FileUserDictionary() {
this("");
}
/**
* Create a FileUserDictionary with the dictionaries on a specific location.
* @param fileBase the base
*/
public FileUserDictionary(String fileBase) {
if (fileBase == null) {
fileBase = "";
}
fileBase = fileBase.trim();
fileBase = fileBase.replace('\\', '/');
if (fileBase.length() > 0 && !fileBase.endsWith("/")) {
fileBase += "/";
}
this.fileBase = fileBase;
}
/**
* {@inheritDoc}
*/
public void addWord(final String word) {
try {
final FileOutputStream output = new FileOutputStream(file, true);
final Writer writer = new OutputStreamWriter(output, "UTF8");
if (file.length() > 0) {
writer.write("\n");
}
writer.write(word);
writer.close();
}
catch (final Exception ex) {
ex.printStackTrace();
}
}
/**
* {@inheritDoc}
*/
public String getUserWords(final Locale locale) {
file = new File(fileBase + "UserDictionary_" + locale + ".txt");
try {
final FileInputStream input = new FileInputStream(file);
final Reader reader = new InputStreamReader(input, "UTF8");
final StringBuilder builder = new StringBuilder();
final char[] buffer = new char[4096];
int count;
while ((count = reader.read(buffer)) > 0) {
builder.append(buffer, 0, count);
}
reader.close();
return builder.toString();
}
catch (final IOException ex) {
/* ignore FileNotFound */
}
return null;
}
/**
* {@inheritDoc}
*/
public void setUserWords(final String wordList) {
try {
final FileOutputStream output = new FileOutputStream(file);
final Writer writer = new OutputStreamWriter(output, "UTF8");
writer.write(wordList);
writer.close();
}
catch (final Exception ex) {
ex.printStackTrace();
}
}
}
freeplane-1.3.15/JOrtho_0.4_freeplane/src/com/inet/jortho/LanguageChangeEvent.java 100664 0 0 3532 12465442703 25023 0 ustar 0 0 /*
* 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 06.12.2007
*/
package com.inet.jortho;
import java.util.Locale;
/**
* This Event is used by LanguageChangeListener
.
* @see LanguageChangeListener
* @author Volker Berlin
*/
public class LanguageChangeEvent {
private final Locale currentLocale;
private final Locale oldLocale;
/**
* Creates a new LanguageChangeEvent
* @param currentLocale the new Locale
* @param oldLocale the old Locale
*/
public LanguageChangeEvent(final Locale currentLocale, final Locale oldLocale) {
this.currentLocale = currentLocale;
this.oldLocale = oldLocale;
}
/**
* Get the value of the current Locale after firing this Event.
* It general it should be equal to {@link SpellChecker#getCurrentLocale()}.
* @return the current Locale
* @see SpellChecker#getCurrentLocale()
*/
public Locale getCurrentLocale() {
return currentLocale;
}
/**
* Gets the value of the old Locale before the firing this Event.
* @return the old Locale
* @see SpellChecker#getCurrentLocale()
*/
public Locale getOldLocale() {
return oldLocale;
}
}
freeplane-1.3.15/JOrtho_0.4_freeplane/src/com/inet/jortho/LanguageChangeListener.java 100664 0 0 3001 12465442703 25516 0 ustar 0 0 /*
* 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 06.12.2007
*/
package com.inet.jortho;
import java.util.EventListener;
/**
* A language change event gets fired whenever the language is changed.
* You can register a LanguageChangeListener in the class SpellChecker.
* @author Volker Berlin
* @see SpellChecker#addLanguageChangeLister(LanguageChangeListener)
* @see SpellChecker#removeLanguageChangeLister(LanguageChangeListener)
*/
public interface LanguageChangeListener extends EventListener {
/**
* This method gets called when the language is changed.
* This occurs if the user selects another language in the languages menu.
* @param ev A LanguageChangeEvent object describing the changes.
*/
public void languageChanged(LanguageChangeEvent ev);
}
freeplane-1.3.15/JOrtho_0.4_freeplane/src/com/inet/jortho/LetterBasedBreakIterator.java 100664 0 0 10042 12465442703 26057 0 ustar 0 0 /*
* Freeplane - mind map editor
* Copyright (C) 2010 dimitry
*
* This file author is dimitry
*
* 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, see .
*/
package com.inet.jortho;
import java.text.BreakIterator;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
/**
* @author Dimitry Polivaev
* Aug 14, 2010
*/
class LetterBasedBreakIterator {
private CharacterIterator text;
public LetterBasedBreakIterator() {
}
/**
* Set a new text string to be scanned. The current scan
* position is reset to first().
* @param newText new text to scan.
*/
public void setText(String newText)
{
setText(new StringCharacterIterator(newText));
}
/**
* Set a new text for scanning. The current scan
* position is reset to first().
* @param newText new text to scan.
*/
public void setText(CharacterIterator text){
this.text = text;
}
/**
* Returns the first boundary. The iterator's current position is set
* to the first text boundary.
* @return The character index of the first text boundary.
*/
public int first() {
return nextBoundary(text.first(), false);
}
private int nextBoundary(char c, boolean wasLetter) {
for(;;){
if(c == CharacterIterator.DONE){
return BreakIterator.DONE;
}
if(wasLetter != isLetter(c)){
return text.getIndex();
}
c = text.next();
}
}
/**
* Returns the first boundary following the specified character offset. If the
* specified offset equals to the last text boundary, it returns
* BreakIterator.DONE
and the iterator's current position is unchanged.
* Otherwise, the iterator's current position is set to the returned boundary.
* The value returned is always greater than the offset or the value
* BreakIterator.DONE
.
* @param offset the character offset to begin scanning.
* @return The first boundary after the specified offset or
* BreakIterator.DONE
if the last text boundary is passed in
* as the offset.
* @exception IllegalArgumentException if the specified offset is less than
* the first text boundary or greater than the last text boundary.
*/
public int following(int wordOffset) {
if(wordOffset <= text.getBeginIndex()){
return first();
}
if(wordOffset >= text.getEndIndex()){
return BreakIterator.DONE;
}
int lastIndex = text.getIndex();
text.setIndex(wordOffset);
boolean wasLetter = isLetter(text.current());
int nextBoundary = nextBoundary(text.next(), wasLetter);
if(nextBoundary == BreakIterator.DONE){
text.setIndex(lastIndex);
}
return nextBoundary;
}
/**
* Returns the boundary following the current boundary. If the current boundary
* is the last text boundary, it returns BreakIterator.DONE
and
* the iterator's current position is unchanged. Otherwise, the iterator's
* current position is set to the boundary following the current boundary.
* @return The character index of the next text boundary or
* BreakIterator.DONE
if the current boundary is the last text
* boundary.
* Equivalent to next(1).
* @see #next(int)
*/
public int next() {
boolean wasLetter = isLetter(text.current());
return nextBoundary(text.next(), wasLetter);
}
private boolean isLetter(char current) {
return Character.isDigit(current) || Character.isLetter(current);
}
}
freeplane-1.3.15/JOrtho_0.4_freeplane/src/com/inet/jortho/PopupListener.java 100664 0 0 3127 12465442703 24001 0 ustar 0 0 /*
* 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 06.12.2007
*/
package com.inet.jortho;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPopupMenu;
/**
* Implement a MouseListener for Popup Event. It simple show the popup if there are the right mouse event. This should
* be part of the standard Java API.
*
* @author Volker Berlin
*/
public class PopupListener extends MouseAdapter {
private final JPopupMenu menu;
public PopupListener(final JPopupMenu menu) {
this.menu = menu;
}
private void maybeShowPopup(final MouseEvent ev) {
if (ev.isPopupTrigger()) {
menu.show(ev.getComponent(), ev.getX(), ev.getY());
}
}
@Override
public void mousePressed(final MouseEvent ev) {
maybeShowPopup(ev);
}
@Override
public void mouseReleased(final MouseEvent ev) {
maybeShowPopup(ev);
}
}
freeplane-1.3.15/JOrtho_0.4_freeplane/src/com/inet/jortho/RedZigZagPainter.java 100664 0 0 5603 12465442703 24342 0 ustar 0 0 /*
* 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 05.11.2005
*/
package com.inet.jortho;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import javax.swing.text.View;
/**
* @author Volker Berlin
*/
class RedZigZagPainter extends DefaultHighlighter.DefaultHighlightPainter {
private static final java.awt.BasicStroke STROKE1 = new java.awt.BasicStroke(0.01F, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10, new float[] { 1, 3 }, 0);
private static final java.awt.BasicStroke STROKE2 = new java.awt.BasicStroke(0.01F, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10, new float[] { 1, 1 }, 1);
private static final java.awt.BasicStroke STROKE3 = new java.awt.BasicStroke(0.01F, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10, new float[] { 1, 3 }, 2);
public RedZigZagPainter() {
super(Color.red);
}
private void drawZigZagLine(final Graphics g, final Rectangle rect) {
final int x1 = rect.x;
final int x2 = x1 + rect.width - 1;
int y = rect.y + rect.height - 1;
final Graphics2D g2 = (Graphics2D) g;
Stroke stroke = g2.getStroke();
g2.setStroke(STROKE1);
g2.drawLine(x1, y, x2, y);
y--;
g2.setStroke(STROKE2);
g2.drawLine(x1, y, x2, y);
y--;
g2.setStroke(STROKE3);
g2.drawLine(x1, y, x2, y);
g2.setStroke(stroke);
}
/**
* {@inheritDoc}
*/
@Override
public Shape paintLayer(final Graphics g, final int i, final int j, final Shape shape, final JTextComponent jtext,
final View view) {
if (jtext.isEditable()) {
g.setColor(Color.red);
try {
final Shape sh = view.modelToView(i, Position.Bias.Forward, j, Position.Bias.Backward, shape);
final Rectangle rect = (sh instanceof Rectangle) ? (Rectangle) sh : sh.getBounds();
drawZigZagLine(g, rect);
return rect;
}
catch (final BadLocationException badlocationexception) {
return null;
}
}
return null;
}
}
freeplane-1.3.15/JOrtho_0.4_freeplane/src/com/inet/jortho/SpellChecker.java 100664 0 0 63331 12465442703 23557 0 ustar 0 0 /*
* 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 05.12.2007
*/
package com.inet.jortho;
import java.awt.Dialog;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;
import java.util.Properties;
import java.util.WeakHashMap;
import javax.swing.AbstractAction;
import javax.swing.ButtonGroup;
import javax.swing.JMenu;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;
/**
* This class is the major class of the spell checker JOrtho (Java Orthography Checker).
* In the most cases this is the only class that you need to add spell checking to your application.
* First you need to do a one-time registration of your dictionaries. In standalone applications this can
* look like:
*
* SpellChecker.registerDictionaries( new URL("file", null, ""), "en,de", "de" );
*
* and in an applet this will look like:
*
* SpellChecker.registerDictionaries( getCodeBase(), "en,de", "en" );
*
* After this you can register your text component that should have the spell checker features
* (Highlighter, context menu, spell checking dialog).
* This looks like:
* JTextPane text = new JTextPane();
* SpellChecker.register( text );
*
* @author Volker Berlin
*/
public class SpellChecker {
private static class ActionToggleButtonModel extends JToggleButton.ToggleButtonModel {
/**
*
*/
private static final long serialVersionUID = 1L;
private final LanguageAction action;
ActionToggleButtonModel(final LanguageAction action) {
this.action = action;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isSelected() {
return Boolean.TRUE.equals(action.getValue(SELECTED_KEY));
}
/**
* {@inheritDoc}
*/
@Override
public void setSelected(boolean b) {
// copy from super.setSelected
final ButtonGroup group = getGroup();
if (group != null) {
// use the group model instead
group.setSelected(this, b);
b = group.isSelected(this);
}
if (isSelected() == b) {
return;
}
action.setSelected(b);
// Send ChangeEvent
fireStateChanged();
// Send ItemEvent
fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, this,
this.isSelected() ? ItemEvent.SELECTED : ItemEvent.DESELECTED));
}
}
private static class DisableLanguageAction extends LanguageAction {
static DisableLanguageAction instance = new DisableLanguageAction();
/**
*
*/
private static final long serialVersionUID = 1L;
private DisableLanguageAction() {
super(Utils.getResource("disable"));
}
@Override
public void actionPerformed(final ActionEvent ev) {
if (!isEnabled()) {
//because multiple MenuItems share the same action that
//also the event occur multiple time
return;
}
setEnabled(false);
setSelected(true);
try {
currentDictionary = null;
final Locale oldLocale = currentLocale;
currentLocale = null;
SpellChecker.fireLanguageChanged(oldLocale);
}
finally {
setEnabled(true);
}
}
@Override
public int compareTo(final LanguageAction obj) {
return equals(obj) ? 0 : 1;
}
@Override
public boolean equals(final Object obj) {
return this == obj;
}
@Override
public int hashCode() {
return getClass().hashCode();
}
@Override
public void setSelected(final boolean b) {
super.setSelected(b);
}
}
/**
* Action for change the current dictionary language.
*/
private static class LanguageAction extends AbstractAction implements Comparable {
// the current active (selected) LanguageAction
private static LanguageAction currentAction;
/**
*
*/
private static final long serialVersionUID = 1L;
private final URL baseURL;
private final String extension;
private final Locale locale;
LanguageAction(final String name) {
super(name);
baseURL = null;
locale = null;
extension = null;
}
LanguageAction(final URL baseURL, final Locale locale, final String extension) {
super(locale.getDisplayLanguage());
this.baseURL = baseURL;
this.locale = locale;
this.extension = extension;
}
public void actionPerformed(final ActionEvent ev) {
if (!isEnabled()) {
//because multiple MenuItems share the same action that
//also the event occur multiple time
return;
}
setEnabled(false);
setSelected(true);
final Locale oldLocale = currentLocale;
currentDictionary = null;
currentLocale = null;
SpellChecker.fireLanguageChanged(oldLocale);
final Thread thread = new Thread(new Runnable() {
public void run() {
try {
final DictionaryFactory factory = new DictionaryFactory();
try {
factory.loadWordList(new URL(baseURL, "dictionary_" + locale + extension));
final UserDictionaryProvider provider = userDictionaryProvider;
if (provider != null) {
final String userWords = provider.getUserWords(locale);
if (userWords != null) {
factory.loadPlainWordList(new StringReader(userWords));
}
}
}
catch (final Exception ex) {
JOptionPane.showMessageDialog(null, ex.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
currentDictionary = factory.create();
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
currentLocale = locale;
SpellChecker.fireLanguageChanged(null);
}
});
}
catch (Exception e) {
e.printStackTrace();
}
}
finally {
setEnabled(true);
}
}
});
thread.setPriority(Thread.NORM_PRIORITY);
thread.setDaemon(true);
thread.start();
}
/**
* Sort the displaynames in the order of the current language
*/
public int compareTo(final LanguageAction obj) {
return toString().compareTo(obj.toString());
}
@Override
public boolean equals(final Object obj) {
if (obj instanceof LanguageAction) {
return locale.equals(((LanguageAction) obj).locale);
}
return false;
}
@Override
public int hashCode() {
return locale.hashCode();
}
/**
* Selects or deselects the menu item.
*
* @param b
* true selects the menu item, false deselects the menu item.
*/
public void setSelected(final boolean b) {
if (b) {
// because there are some problems with multiple ButtonGroups that we duplicate some of the logic here
if (currentAction != null && currentAction != this) {
currentAction.setSelected(false);
}
currentAction = this;
}
putValue(SELECTED_KEY, Boolean.valueOf(b));
}
public Locale getLocale() {
return locale;
}
}
private static String applicationName;
private static Dictionary currentDictionary;
private static Locale currentLocale;
private static final SpellCheckerOptions globalOptions = new SpellCheckerOptions();
private final static ArrayList languages = new ArrayList();
private final static java.util.Map listeners = Collections
.synchronizedMap(new WeakHashMap());
/**
* Duplicate of Action.SELECTED_KEY since 1.6
*/
static final String SELECTED_KEY = "SwingSelectedKey";
private static UserDictionaryProvider userDictionaryProvider;
/**
* Adds the LanguageChangeListener. You do not need to remove if the
* LanguageChangeListener is not needed anymore.
* @param listener listener to add
* @see LanguageChangeListener
*/
public static void addLanguageChangeLister(final LanguageChangeListener listener) {
listeners.put(listener, null);
}
/**
* Creates a menu item "Orthography" (or the equivalent depending on the user language) with a
* sub-menu that includes suggestions for a correct spelling.
* You can use this to add this menu item to your own popup.
* @return the new menu.
*/
public static JMenu createCheckerMenu() {
return SpellChecker.createCheckerMenu(null);
}
/**
* Creates a menu item "Orthography" (or the equivalent depending on the user language) with a
* sub-menu that includes suggestions for a correct spelling.
* You can use this to add this menu item to your own popup.
* @param options override the default options for this menu.
* @return the new menu.
*/
public static JMenu createCheckerMenu(final SpellCheckerOptions options) {
return new CheckerMenu(options);
}
/**
* Create a dynamic JPopupMenu with a list of suggestion. You can use the follow code sequence:
* JPopupMenu popup = SpellChecker.createCheckerPopup();
* text.addMouseListener( new PopupListener(popup) );
*
* @return the new JPopupMenu.
* @see #createCheckerMenu()
*/
public static JPopupMenu createCheckerPopup() {
return SpellChecker.createCheckerPopup(null);
}
/**
* Create a dynamic JPopupMenu with a list of suggestion. You can use the follow code sequence:
* JPopupMenu popup = SpellChecker.createCheckerPopup( null );
* text.addMouseListener( new PopupListener(popup) );
*
* @return the new JPopupMenu.
* @see #createCheckerMenu(SpellCheckerOptions)
*/
public static JPopupMenu createCheckerPopup(final SpellCheckerOptions options) {
return new CheckerPopup(options);
}
/**
* Creates a menu item "Languages" (or the equivalent depending on the user language) with a sub-menu
* that lists all available dictionary languages.
* You can use this to add this menu item to your own popup or to your menu bar.
*
* JPopupMenu popup = new JPopupMenu();
* popup.add( SpellChecker.createLanguagesMenu() );
*
* @return the new menu.
*/
public static JMenu createLanguagesMenu() {
final JMenu menu = new JMenu(Utils.getResource("languages"));
final ButtonGroup group = new ButtonGroup();
menu.setEnabled(languages.size() > 0);
for (final LanguageAction action : languages) {
final JRadioButtonMenuItem item = new JRadioButtonMenuItem(action);
//Hack that all items of the action have the same state.
//http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4133141
item.setModel(new ActionToggleButtonModel(action));
menu.add(item);
group.add(item);
}
if (languages.size() > 0) {
menu.addSeparator();
final JRadioButtonMenuItem item = new JRadioButtonMenuItem(DisableLanguageAction.instance);
item.setModel(new ActionToggleButtonModel(DisableLanguageAction.instance));
menu.add(item);
group.add(item);
}
return menu;
}
/**
* Enable or disable the auto spell checking feature (red zigzag line) for a text component.
* If you change the document then you need to reenable it.
*
* @param text
* the JTextComponent that should change
* @param enable
* true, enable the feature.
*/
public static void enableAutoSpell(final JTextComponent text, final boolean enable) {
SpellChecker.enableAutoSpell(text, enable, null);
}
/**
* Enable or disable the auto spell checking feature (red zigzag line) for a text component. If you change the
* document then you need to reenable it.
*
* @param text
* the JTextComponent that should change
* @param enable
* true, enable the feature.
* @param options
* override the default options for this menu.
*/
public static void enableAutoSpell(final JTextComponent text, final boolean enable,
final SpellCheckerOptions options) {
if (enable) {
new AutoSpellChecker(text, options);
}
else {
AutoSpellChecker.disable(text);
}
}
/**
* Enable or disable the popup menu with the menu item "Orthography" and "Languages".
* @param text the JTextComponent that should change
* @param enable true, enable the feature.
*/
public static void enablePopup(final JTextComponent text, final boolean enable) {
if (enable) {
final JPopupMenu menu = new JPopupMenu();
menu.add(SpellChecker.createCheckerMenu());
menu.add(SpellChecker.createLanguagesMenu());
text.addMouseListener(new PopupListener(menu));
}
else {
for (final MouseListener listener : text.getMouseListeners()) {
if (listener instanceof PopupListener) {
text.removeMouseListener(listener);
}
}
}
}
/**
* Enable or disable the F7 key. Pressing the F7 key will display the spell check dialog. This also
* register an Action with the name "spell-checking".
* @param text the JTextComponent that should change
* @param enable true, enable the feature.
*/
public static void enableShortKey(final JTextComponent text, final boolean enable) {
SpellChecker.enableShortKey(text, enable, null);
}
/**
* Enable or disable the F7 key. Pressing the F7 key will display the spell check dialog. This also
* register an Action with the name "spell-checking".
* @param text the JTextComponent that should change
* @param enable true, enable the feature.
* @param options override the default options for this menu.
*/
public static void enableShortKey(final JTextComponent text, final boolean enable, final SpellCheckerOptions options) {
if (enable) {
text.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F7, 0), "spell-checking");
text.getActionMap().put("spell-checking", new AbstractAction() {
/**
*
*/
private static final long serialVersionUID = 1L;
public void actionPerformed(final ActionEvent e) {
SpellChecker.showSpellCheckerDialog(text, options);
}
});
}
else {
text.getActionMap().remove("spell-checking");
}
}
/**
* Helper method to fire an Language change event.
*/
private static void fireLanguageChanged(final Locale oldLocale) {
final LanguageChangeEvent ev = new LanguageChangeEvent(currentLocale, oldLocale);
synchronized(listeners){
for (final LanguageChangeListener listener : listeners.keySet()) {
listener.languageChanged(ev);
}
}
}
/**
* Get the title of your application.
*/
public static String getApplicationName() {
return applicationName;
}
/**
* Get the current Dictionary
. The current dictionary will be set if the user one select or on calling registerDictionaries
.
* @return the current Dictionary
or null if not set.
* @see #registerDictionaries(URL, String, String)
*/
public static Dictionary getCurrentDictionary() {
return currentDictionary;
}
/**
* Gets the current Locale
. The current Locale will be set if the user selects
* one, or when calling registerDictionaries.
* @return the current Locale
or null if none is set.
* @see #registerDictionaries(URL, String, String)
*/
public static Locale getCurrentLocale() {
return currentLocale;
}
/**
* Get the default SpellCheckerOptions. This object is a singleton. That there is no get method.
* @return the default SpellCheckerOptions
*/
public static SpellCheckerOptions getOptions() {
return globalOptions;
}
/**
* Gets the currently set UserDictionaryProvider. If none has been set then null is returned.
*
* @see #setUserDictionaryProvider(UserDictionaryProvider)
*/
static UserDictionaryProvider getUserDictionaryProvider() {
return SpellChecker.userDictionaryProvider;
}
/**
* Activate the spell checker for the given JTextComponent
. The call is equal to register( text,
* true, true ).
*
* @param text
* the JTextComponent
* @throws NullPointerException
* if text is null
*/
public static void register(final JTextComponent text) throws NullPointerException {
SpellChecker.register(text, true, true, true);
}
/**
* Activates the spell checker for the given JTextComponent
. You do not need to unregister if the
* JTextComponent is not needed anymore.
*
* @param text
* the JTextComponent
* @param hasPopup
* if true, the JTextComponent is to have a popup menu with the menu item "Orthography" and "Languages".
* @param hasShortKey
* if true, pressing the F7 key will display the spell check dialog.
* @param hasAutoSpell
* if true, the JTextComponent has a auto spell checking.
* @throws NullPointerException
* if text is null
*/
public static void register(final JTextComponent text, final boolean hasPopup, final boolean hasShortKey,
final boolean hasAutoSpell) throws NullPointerException {
if (hasPopup) {
SpellChecker.enablePopup(text, true);
}
if (hasShortKey) {
SpellChecker.enableShortKey(text, true);
}
if (hasAutoSpell) {
SpellChecker.enableAutoSpell(text, true);
}
}
/**
* Registers the available dictionaries. The dictionaries' URLs must have the form "dictionary_xx.xxxxx" and must be
* relative to the baseURL. The available languages and extension of the dictionaries is load from a configuration file.
* The configuration file must also relative to the baseURL and must be named dictionaries.cnf, dictionaries.properties or
* dictionaries.txt. If the dictionary of the active Locale does not exist, the first dictionary is loaded. There is
* only one dictionary loaded in memory at a given time. The configuration file has a Java Properties format. Currently
* there are the follow options:
*
* - languages
* - extension
*
*
* @param baseURL
* the base URL where the dictionaries and configuration file can be found. If null then URL("file", null, "")
* is used.
* @param activeLocale
* the locale that should be loaded and made active. If null or empty then the default locale is used.
*/
public static void registerDictionaries(URL baseURL, final String activeLocale) {
if (baseURL == null) {
try {
baseURL = new URL("file", null, "");
}
catch (final MalformedURLException e) {
// should never occur because the URL is valid
e.printStackTrace();
}
}
InputStream input;
try {
input = new URL(baseURL, "dictionaries.cnf").openStream();
}
catch (final Exception e1) {
try {
input = new URL(baseURL, "dictionaries.properties").openStream();
}
catch (final Exception e2) {
try {
input = new URL(baseURL, "dictionaries.txt").openStream();
}
catch (final Exception e3) {
System.err.println("JOrtho configuration file not found!");
e1.printStackTrace();
e2.printStackTrace();
e3.printStackTrace();
return;
}
}
}
final Properties props = new Properties();
try {
props.load(input);
}
catch (final IOException e) {
e.printStackTrace();
return;
}
final String availableLocales = props.getProperty("languages");
final String extension = props.getProperty("extension", ".ortho");
SpellChecker.registerDictionaries(baseURL, availableLocales, activeLocale, extension);
}
/**
* Registers the available dictionaries. The dictionaries' URLs must have the form "dictionary_xx.ortho" and must be
* relative to the baseURL. If the dictionary of the active Locale does not exist, the first dictionary is loaded.
* There is only one dictionary loaded in memory at a given time.
*
* @param baseURL
* the base URL where the dictionaries can be found. If null then URL("file", null, "") is used.
* @param availableLocales
* a comma separated list of locales
* @param activeLocale
* the locale that should be loaded and made active. If null or empty then the default locale is used.
* @see #setUserDictionaryProvider(UserDictionaryProvider)
*/
public static void registerDictionaries(final URL baseURL, final String availableLocales, final String activeLocale) {
SpellChecker.registerDictionaries(baseURL, availableLocales, activeLocale, ".ortho");
}
/**
* Registers the available dictionaries. The dictionaries' URLs must have the form "dictionary_xx.xxxxx" and must be
* relative to the baseURL. The extension can be set via parameter.
* If the dictionary of the active Locale does not exist, the first dictionary is loaded.
* There is only one dictionary loaded in memory at a given time.
*
* @param baseURL
* the base URL where the dictionaries can be found. If null then URL("file", null, "") is used.
* @param availableLocales
* a comma separated list of locales
* @param activeLocale
* the locale that should be loaded and made active. If null or empty then the default locale is used.
* @param extension
* the file extension of the dictionaries. Some web server like the IIS6 does not support the default ".ortho".
* @see #setUserDictionaryProvider(UserDictionaryProvider)
*/
public static void registerDictionaries(URL baseURL, final String availableLocales, String activeLocale,
final String extension) {
if (baseURL == null) {
try {
baseURL = new URL("file", null, "");
}
catch (final MalformedURLException e) {
// should never occur because the URL is valid
e.printStackTrace();
}
}
for (String locale : availableLocales.split(",")) {
locale = locale.trim().toLowerCase();
if (locale.length() > 0) {
final LanguageAction action = new LanguageAction(baseURL, new Locale(locale), extension);
languages.remove(action);
languages.add(action);
}
}
//sort the display names in order of the current language
Collections.sort(languages);
setLanguage(activeLocale);
}
public static void setLanguage(String activeLocale) {
boolean activeSelected = false;
if (activeLocale != null) {
activeLocale = activeLocale.trim();
for(LanguageAction language:languages){
if (language.getLocale().getLanguage().equals(activeLocale)) {
language.actionPerformed(null);
activeSelected = true;
}
}
}
// if nothing selected then select the first entry
if (!activeSelected && languages.size() > 0) {
DisableLanguageAction.instance.actionPerformed(null);
}
}
public static String getLanguage(){
return currentLocale == null ? null : currentLocale.getLanguage();
}
/**
* Removes the LanguageChangeListener.
* @param listener listener to remove
*/
public static void removeLanguageChangeLister(final LanguageChangeListener listener) {
listeners.remove(listener);
}
/**
* Set the title of your application. This valuse is used as title for info boxes (JOptionPane).
* If not set then the translated "Spelling" is used.
*/
public static void setApplicationName(final String name) {
applicationName = name;
}
/**
* Sets the UserDictionaryProvider. This is needed if the user should be able to add their own words.
* This method must be called before {@link #registerDictionaries(URL, String, String)}.
*
* @param userDictionaryProvider the new UserDictionaryProvider or null
* @see #getUserDictionaryProvider()
* @see #registerDictionaries(URL, String, String)
*/
public static void setUserDictionaryProvider(final UserDictionaryProvider userDictionaryProvider) {
SpellChecker.userDictionaryProvider = userDictionaryProvider;
}
/**
* Show the Spell Checker dialog for the given JTextComponent. It will be do nothing if
* the JTextComponent is not editable or there are no dictionary loaded.
* The action for this method can you receive via:
*
* Action action = text.getActionMap().get("spell-checking");
*
* The action is only available if you have enable the short key (F7).
* @param text JTextComponent to check
* @param options override the default options for this menu.
*/
public static void showSpellCheckerDialog(final JTextComponent text, final SpellCheckerOptions options) {
if (!text.isEditable()) {
// only editable text component have spell checking
return;
}
final Dictionary dictionary = currentDictionary;
if (dictionary != null) {
final Window parent = SwingUtilities.getWindowAncestor(text);
SpellCheckerDialog dialog;
if (parent instanceof Frame) {
dialog = new SpellCheckerDialog((Frame) parent, true, options);
}
else {
dialog = new SpellCheckerDialog((Dialog) parent, true, options);
}
dialog.show(text, dictionary, currentLocale);
}
}
/**
* Removes all spell checker features from the JTextComponent. This does not need to be called
* if the text component is no longer needed.
* @param text the JTextComponent
*/
public static void unregister(final JTextComponent text) {
SpellChecker.enableShortKey(text, false);
SpellChecker.enablePopup(text, false);
SpellChecker.enableAutoSpell(text, false);
}
/**
* There is no instance needed of SpellChecker. All methods are static.
*/
private SpellChecker() {/*nothing*/
}
}
freeplane-1.3.15/JOrtho_0.4_freeplane/src/com/inet/jortho/SpellCheckerDialog.java 100664 0 0 30252 12465442703 24673 0 ustar 0 0 /*
* 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 10.11.2005
*/
package com.inet.jortho;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.JTextComponent;
/**
* The Dialog for continues checking the orthography.
* @author Volker Berlin
*/
class SpellCheckerDialog extends JDialog implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
final private JButton addToDic = new JButton(Utils.getResource("addToDictionary"));
final private JButton change = new JButton(Utils.getResource("change"));
final private JButton changeAll = new JButton(Utils.getResource("changeAll"));
/** Map of change all words */
final private HashMap changeWords = new HashMap();
final private JButton close = new JButton(Utils.getResource("close"));
private Dictionary dictionary;
final private JButton editDic = new JButton(Utils.getResource("editDictionary"));
final private JButton ignore = new JButton(Utils.getResource("ignore"));
final private JButton ignoreAll = new JButton(Utils.getResource("ignoreAll"));
/** List of ignore all words */
final private ArrayList ignoreWords = new ArrayList();
private boolean isDictionaryModify;
private JTextComponent jText;
final private JLabel notFound = new JLabel();
private final SpellCheckerOptions options;
final private JList suggestionsList = new JList();
private Tokenizer tok;
final private JTextField word = new JTextField();
SpellCheckerDialog(final Dialog owner) throws HeadlessException {
this(owner, false, null);
}
SpellCheckerDialog(final Dialog owner, final boolean modal, final SpellCheckerOptions options) {
super(owner, modal);
this.options = options == null ? SpellChecker.getOptions() : options;
init();
}
SpellCheckerDialog(final Frame owner) {
this(owner, false, null);
}
SpellCheckerDialog(final Frame owner, final boolean modal, final SpellCheckerOptions options) {
super(owner, modal);
this.options = options == null ? SpellChecker.getOptions() : options;
init();
}
public void actionPerformed(final ActionEvent ev) {
final Object source = ev.getSource();
if (source == ignore) {
searchNext();
}
else if (source == close) {
dispose();
}
else {
final String newWord = word.getText();
final String oldWord = notFound.getText();
if (source == ignoreAll) {
ignoreWords.add(oldWord);
searchNext();
}
else if (source == addToDic) {
final UserDictionaryProvider provider = SpellChecker.getUserDictionaryProvider();
if (provider != null) {
provider.addWord(oldWord);
}
dictionary.add(oldWord);
dictionary.trimToSize();
isDictionaryModify = true;
searchNext();
}
else if (source == editDic) {
new DictionaryEditDialog(this).setVisible(true);
}
else if (source == change) {
replaceWord(oldWord, newWord);
searchNext();
}
else if (source == changeAll) {
changeWords.put(oldWord, newWord);
replaceWord(oldWord, newWord);
searchNext();
}
}
}
@Override
public void dispose() {
super.dispose();
if (isDictionaryModify) {
AutoSpellChecker.refresh(jText);
}
}
final private void init() {
try {
final Image image = ImageIO.read(getClass().getResourceAsStream("icon.png"));
// setIconImage appeared in Java 6.0 so use reflection to be compatible
// with earlier JVMs. Equivalent to calling setIcomImage(image);
final Class