mirror of https://github.com/sipwise/jitsi.git
parent
e46f74f442
commit
801a79ca9d
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 609 B |
@ -0,0 +1,508 @@
|
|||||||
|
/*
|
||||||
|
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||||
|
*
|
||||||
|
* Distributable under LGPL license. See terms of license at gnu.org.
|
||||||
|
*/
|
||||||
|
package net.java.sip.communicator.plugin.spellcheck;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.*;
|
||||||
|
|
||||||
|
import net.java.sip.communicator.plugin.spellcheck.Parameters.Default;
|
||||||
|
import net.java.sip.communicator.service.contactlist.*;
|
||||||
|
import net.java.sip.communicator.service.gui.*;
|
||||||
|
import net.java.sip.communicator.service.gui.Container;
|
||||||
|
import net.java.sip.communicator.service.protocol.Contact;
|
||||||
|
import net.java.sip.communicator.util.*;
|
||||||
|
import net.java.sip.communicator.util.swing.*;
|
||||||
|
import net.java.sip.communicator.util.swing.SwingWorker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combo box providing a listing of all available locales with corresponding
|
||||||
|
* country flags. Selecting a new field causes that locale's dictionary to be
|
||||||
|
* downloaded, if not available. The spell checker then use the selected
|
||||||
|
* language for further checking.
|
||||||
|
*
|
||||||
|
* @author Damian Johnson
|
||||||
|
* @author Yana Stamcheva
|
||||||
|
*/
|
||||||
|
public class LanguageSelectionField
|
||||||
|
extends SIPCommMenuBar
|
||||||
|
implements PluginComponent
|
||||||
|
{
|
||||||
|
private static final HashMap<SpellChecker, LanguageSelectionField>
|
||||||
|
CLASS_INSTANCES =
|
||||||
|
new HashMap<SpellChecker, LanguageSelectionField>();
|
||||||
|
|
||||||
|
// parallel maps containing cached instances of country flags
|
||||||
|
private static final HashMap<Parameters.Locale, ImageIcon>
|
||||||
|
AVAILABLE_FLAGS = new HashMap<Parameters.Locale, ImageIcon>();
|
||||||
|
|
||||||
|
private static final HashMap<Parameters.Locale, ImageIcon>
|
||||||
|
UNAVAILABLE_FLAGS = new HashMap<Parameters.Locale, ImageIcon>();
|
||||||
|
|
||||||
|
private static final Logger logger = Logger
|
||||||
|
.getLogger(LanguageSelectionField.class);
|
||||||
|
|
||||||
|
private static final ImageIcon BLANK_FLAG_ICON = Resources
|
||||||
|
.getImage("blankFlag");
|
||||||
|
|
||||||
|
private final ListCellRenderer languageSelectionRenderer;
|
||||||
|
|
||||||
|
private final HashMap<Parameters.Locale, Boolean> localeAvailabilityCache =
|
||||||
|
new HashMap<Parameters.Locale, Boolean>();
|
||||||
|
|
||||||
|
private final SpellChecker spellChecker;
|
||||||
|
|
||||||
|
private final SIPCommMenu menu = new SelectorMenu();
|
||||||
|
|
||||||
|
private final ArrayList<Parameters.Locale> localeList =
|
||||||
|
new ArrayList<Parameters.Locale>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides instance of this class associated with a spell checker. If ones
|
||||||
|
* already been created then this instance is used.
|
||||||
|
*
|
||||||
|
* @param checker spell checker field is to be associated with
|
||||||
|
* @return spell checker locale selection field
|
||||||
|
*/
|
||||||
|
public synchronized static LanguageSelectionField makeSelectionField(
|
||||||
|
SpellChecker checker)
|
||||||
|
{
|
||||||
|
// singleton constructor to ensure only one combo box is associated with
|
||||||
|
// each checker
|
||||||
|
if (CLASS_INSTANCES.containsKey(checker))
|
||||||
|
return CLASS_INSTANCES.get(checker);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LanguageSelectionField instance =
|
||||||
|
new LanguageSelectionField(checker);
|
||||||
|
CLASS_INSTANCES.put(checker, instance);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LanguageSelectionField(SpellChecker checker)
|
||||||
|
{
|
||||||
|
this.spellChecker = checker;
|
||||||
|
|
||||||
|
setPreferredSize(new Dimension(30, 28));
|
||||||
|
setMaximumSize(new Dimension(30, 28));
|
||||||
|
setMinimumSize(new Dimension(30, 28));
|
||||||
|
|
||||||
|
this.menu.setPreferredSize(new Dimension(30, 45));
|
||||||
|
this.menu.setMaximumSize(new Dimension(30, 45));
|
||||||
|
|
||||||
|
this.add(menu);
|
||||||
|
|
||||||
|
this.setBorder(null);
|
||||||
|
this.menu.add(createEnableCheckBox());
|
||||||
|
this.menu.addSeparator();
|
||||||
|
this.menu.setBorder(null);
|
||||||
|
this.menu.setOpaque(false);
|
||||||
|
this.setOpaque(false);
|
||||||
|
|
||||||
|
DefaultListModel model = new DefaultListModel();
|
||||||
|
final JList list = new JList(model);
|
||||||
|
|
||||||
|
this.languageSelectionRenderer = new LanguageListRenderer();
|
||||||
|
|
||||||
|
for (Parameters.Locale locale : Parameters.getLocales())
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!localeAvailabilityCache.containsKey(locale))
|
||||||
|
{
|
||||||
|
localeAvailabilityCache.put(locale,
|
||||||
|
spellChecker.isLocaleAvailable(locale));
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addElement(locale);
|
||||||
|
localeList.add(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
JScrollPane scroll = new JScrollPane(list);
|
||||||
|
scroll.setBorder(null);
|
||||||
|
|
||||||
|
String localeIso = Parameters.getDefault(Default.LOCALE);
|
||||||
|
Parameters.Locale loc = Parameters.getLocale(localeIso);
|
||||||
|
|
||||||
|
list.setCellRenderer(languageSelectionRenderer);
|
||||||
|
list.setSelectedIndex(localeList.indexOf(loc) + 1);
|
||||||
|
|
||||||
|
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
|
||||||
|
list.addListSelectionListener(new ListSelectionListener()
|
||||||
|
{
|
||||||
|
|
||||||
|
public void valueChanged(ListSelectionEvent e)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!e.getValueIsAdjusting())
|
||||||
|
{
|
||||||
|
final JList source = (JList) e.getSource();
|
||||||
|
final Parameters.Locale locale =
|
||||||
|
(Parameters.Locale) source.getSelectedValue();
|
||||||
|
|
||||||
|
source.setEnabled(false);
|
||||||
|
|
||||||
|
// Indicate to the user that the language is currently
|
||||||
|
// loading.
|
||||||
|
locale.setLoading(true);
|
||||||
|
|
||||||
|
new SetSpellChecker(locale, source).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.add(scroll);
|
||||||
|
|
||||||
|
ImageIcon flagIcon =
|
||||||
|
getLocaleIcon(checker.getLocale(),
|
||||||
|
localeAvailabilityCache.get(checker.getLocale()));
|
||||||
|
SelectedObject selectedObject =
|
||||||
|
new SelectedObject(flagIcon, checker.getLocale());
|
||||||
|
menu.setSelected(selectedObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears any cached data used by the field so it reflects the current state
|
||||||
|
* of its associated spell checker.
|
||||||
|
*/
|
||||||
|
// public void revalidate()
|
||||||
|
// {
|
||||||
|
// this.localeAvailabilityCache.clear();
|
||||||
|
// this.field.setSelectedItem(this.spellChecker.getLocale());
|
||||||
|
// }
|
||||||
|
|
||||||
|
public String getConstraints()
|
||||||
|
{
|
||||||
|
return Container.RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Container getContainer()
|
||||||
|
{
|
||||||
|
return Container.CONTAINER_CHAT_TOOL_BAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return "Spell Checker Toggle";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPositionIndex()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNativeComponent()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentContact(MetaContact metaContact)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentContactGroup(MetaContactGroup metaGroup)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImageIcon getLocaleIcon(Parameters.Locale locale,
|
||||||
|
boolean isAvailable)
|
||||||
|
{
|
||||||
|
if (isAvailable && AVAILABLE_FLAGS.containsKey(locale))
|
||||||
|
return AVAILABLE_FLAGS.get(locale);
|
||||||
|
else if (!isAvailable && UNAVAILABLE_FLAGS.containsKey(locale))
|
||||||
|
return UNAVAILABLE_FLAGS.get(locale);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// load resource
|
||||||
|
ImageIcon localeFlag;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int commaIndex = locale.getIsoCode().indexOf(",");
|
||||||
|
String countryCode =
|
||||||
|
locale.getIsoCode().substring(commaIndex + 1);
|
||||||
|
localeFlag = Resources.getFlagImage(countryCode);
|
||||||
|
|
||||||
|
BufferedImage flagBuffer = copy(localeFlag.getImage());
|
||||||
|
setFaded(flagBuffer);
|
||||||
|
ImageIcon unavailableLocaleFlag = new ImageIcon(flagBuffer);
|
||||||
|
|
||||||
|
AVAILABLE_FLAGS.put(locale, localeFlag);
|
||||||
|
UNAVAILABLE_FLAGS.put(locale, unavailableLocaleFlag);
|
||||||
|
return isAvailable ? localeFlag : unavailableLocaleFlag;
|
||||||
|
}
|
||||||
|
catch (IOException exc)
|
||||||
|
{
|
||||||
|
AVAILABLE_FLAGS.put(locale, BLANK_FLAG_ICON);
|
||||||
|
UNAVAILABLE_FLAGS.put(locale, BLANK_FLAG_ICON);
|
||||||
|
return BLANK_FLAG_ICON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a deep copy of an image.
|
||||||
|
*
|
||||||
|
* @param image picture to be processed
|
||||||
|
* @return copy of the image
|
||||||
|
*/
|
||||||
|
private static BufferedImage copy(Image image)
|
||||||
|
{
|
||||||
|
int width = image.getWidth(null);
|
||||||
|
int height = image.getHeight(null);
|
||||||
|
|
||||||
|
BufferedImage copy;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
|
||||||
|
pg.grabPixels();
|
||||||
|
ColorModel cm = pg.getColorModel();
|
||||||
|
|
||||||
|
WritableRaster raster =
|
||||||
|
cm.createCompatibleWritableRaster(width, height);
|
||||||
|
boolean isRasterPremultiplied = cm.isAlphaPremultiplied();
|
||||||
|
copy = new BufferedImage(cm, raster, isRasterPremultiplied, null);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
copy =
|
||||||
|
new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics2D g2 = copy.createGraphics();
|
||||||
|
g2.setComposite(AlphaComposite.Src); // Preserves color of
|
||||||
|
// transparent pixels
|
||||||
|
g2.drawImage(image, 0, 0, null);
|
||||||
|
g2.dispose();
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all color from an image and makes it partly translucent. Original
|
||||||
|
* grayscale method written by Marty Stepp.
|
||||||
|
*
|
||||||
|
* @param image picture to be processed
|
||||||
|
*/
|
||||||
|
private static void setFaded(BufferedImage image)
|
||||||
|
{
|
||||||
|
int width = image.getWidth();
|
||||||
|
int height = image.getHeight();
|
||||||
|
|
||||||
|
for (int row = 0; row < width; ++row)
|
||||||
|
{
|
||||||
|
for (int col = 0; col < height; ++col)
|
||||||
|
{
|
||||||
|
int c = image.getRGB(row, col);
|
||||||
|
|
||||||
|
int r =
|
||||||
|
(((c >> 16) & 0xff) + ((c >> 8) & 0xff) + (c & 0xff)) / 3;
|
||||||
|
|
||||||
|
int newRgb = (0xff << 24) | (r << 16) | (r << 8) | r;
|
||||||
|
newRgb &= (1 << 24) - 1; // Blanks alpha value
|
||||||
|
newRgb |= 128 << 24; // Resets it to the alpha of 128
|
||||||
|
image.setRGB(row, col, newRgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentContact(Contact contact)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SelectorMenu
|
||||||
|
extends SIPCommMenu
|
||||||
|
{
|
||||||
|
Image image = Resources.getImage("service.gui.icons.DOWN_ARROW_ICON")
|
||||||
|
.getImage();
|
||||||
|
|
||||||
|
public void paintComponent(Graphics g)
|
||||||
|
{
|
||||||
|
super.paintComponent(g);
|
||||||
|
|
||||||
|
g.drawImage(image, getWidth() - image.getWidth(this) - 1,
|
||||||
|
(getHeight() - image.getHeight(this) - 1) / 2, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the enable spell check checkbox.
|
||||||
|
*
|
||||||
|
* @return the created checkbox
|
||||||
|
*/
|
||||||
|
private JCheckBox createEnableCheckBox()
|
||||||
|
{
|
||||||
|
final JCheckBox checkBox = new SIPCommCheckBox(
|
||||||
|
Resources.getString("plugin.spellcheck.ENABLE_SPELL_CHECK"));
|
||||||
|
|
||||||
|
checkBox.setSelected(spellChecker.isEnabled());
|
||||||
|
checkBox.setIconTextGap(0);
|
||||||
|
checkBox.addChangeListener(new ChangeListener()
|
||||||
|
{
|
||||||
|
public void stateChanged(ChangeEvent evt)
|
||||||
|
{
|
||||||
|
spellChecker.setEnabled(checkBox.isSelected());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return checkBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SetSpellChecker extends SwingWorker
|
||||||
|
{
|
||||||
|
private final Parameters.Locale locale;
|
||||||
|
|
||||||
|
private final JList sourceList;
|
||||||
|
|
||||||
|
private boolean skipFiring = false;
|
||||||
|
|
||||||
|
public SetSpellChecker( Parameters.Locale locale,
|
||||||
|
JList sourceList)
|
||||||
|
{
|
||||||
|
this.locale = locale;
|
||||||
|
this.sourceList = sourceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on the event dispatching thread (not on the worker thread)
|
||||||
|
* after the <code>construct</code> method has returned.
|
||||||
|
*/
|
||||||
|
public void finished()
|
||||||
|
{
|
||||||
|
if (getValue() != null)
|
||||||
|
{
|
||||||
|
sourceList.setEnabled(true);
|
||||||
|
|
||||||
|
localeAvailabilityCache.put(locale, true);
|
||||||
|
|
||||||
|
ImageIcon flagIcon = getLocaleIcon(locale,
|
||||||
|
localeAvailabilityCache.get(locale));
|
||||||
|
|
||||||
|
SelectedObject selectedObject =
|
||||||
|
new SelectedObject(flagIcon, locale);
|
||||||
|
|
||||||
|
menu.setSelected(selectedObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// reverts selection
|
||||||
|
skipFiring = true;
|
||||||
|
|
||||||
|
// source.setSelectedItem(spellChecker.getLocale());
|
||||||
|
ImageIcon flagIcon =
|
||||||
|
getLocaleIcon(locale,
|
||||||
|
localeAvailabilityCache.get(locale));
|
||||||
|
|
||||||
|
SelectedObject selectedObject =
|
||||||
|
new SelectedObject(flagIcon, locale);
|
||||||
|
|
||||||
|
menu.setSelected(selectedObject);
|
||||||
|
|
||||||
|
skipFiring = false;
|
||||||
|
|
||||||
|
sourceList.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indicate to the user that the language is currently
|
||||||
|
// loading.
|
||||||
|
locale.setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download the dictionary.
|
||||||
|
*/
|
||||||
|
public Object construct() throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// prevents potential infinite loop during errors
|
||||||
|
if (this.skipFiring)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
spellChecker.setLocale(locale);
|
||||||
|
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
logger.warn(
|
||||||
|
"Unable to retrieve dictionary for " + locale, exc);
|
||||||
|
|
||||||
|
// warns that it didn't work
|
||||||
|
PopupDialog dialog =
|
||||||
|
SpellCheckActivator.getUIService()
|
||||||
|
.getPopupDialog();
|
||||||
|
String message
|
||||||
|
= Resources.getString(
|
||||||
|
"plugin.spellcheck.DICT_ERROR");
|
||||||
|
if (exc instanceof IOException)
|
||||||
|
{
|
||||||
|
message = Resources.getString(
|
||||||
|
"plugin.spellcheck.DICT_RETRIEVE_ERROR")
|
||||||
|
+ ":\n" + locale.getDictUrl();
|
||||||
|
}
|
||||||
|
else if (exc instanceof IllegalArgumentException)
|
||||||
|
{
|
||||||
|
message = Resources.getString(
|
||||||
|
"plugin.spellcheck.DICT_PROCESS_ERROR");
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.showMessagePopupDialog(
|
||||||
|
message,
|
||||||
|
Resources
|
||||||
|
.getString("plugin.spellcheck.DICT_ERROR_TITLE"),
|
||||||
|
PopupDialog.WARNING_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom renderer for languages list, transforming a Locale to a row
|
||||||
|
* with an icon and text.
|
||||||
|
*/
|
||||||
|
private class LanguageListRenderer
|
||||||
|
extends DefaultListCellRenderer
|
||||||
|
{
|
||||||
|
public Component getListCellRendererComponent(JList list,
|
||||||
|
Object value, int index, boolean isSelected,
|
||||||
|
boolean cellHasFocus)
|
||||||
|
{
|
||||||
|
Parameters.Locale locale = (Parameters.Locale) value;
|
||||||
|
|
||||||
|
if (!localeAvailabilityCache.containsKey(locale))
|
||||||
|
{
|
||||||
|
localeAvailabilityCache.put(locale,
|
||||||
|
spellChecker.isLocaleAvailable(locale));
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageIcon flagIcon =
|
||||||
|
getLocaleIcon(locale, localeAvailabilityCache.get(locale));
|
||||||
|
|
||||||
|
String localeLabel = locale.getLabel();
|
||||||
|
|
||||||
|
if (locale.isLoading())
|
||||||
|
setText("<html>" + localeLabel
|
||||||
|
+ " <font color='gray'><i>loading...</i></font><html>");
|
||||||
|
else
|
||||||
|
setText(localeLabel);
|
||||||
|
|
||||||
|
setIcon(flagIcon);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,411 @@
|
|||||||
|
/*
|
||||||
|
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||||
|
*
|
||||||
|
* Distributable under LGPL license. See terms of license at gnu.org.
|
||||||
|
*/
|
||||||
|
package net.java.sip.communicator.plugin.spellcheck;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.*;
|
||||||
|
import javax.swing.text.*;
|
||||||
|
|
||||||
|
import org.dts.spell.dictionary.*;
|
||||||
|
|
||||||
|
import net.java.sip.communicator.service.gui.*;
|
||||||
|
import net.java.sip.communicator.service.resources.*;
|
||||||
|
import net.java.sip.communicator.util.Logger;
|
||||||
|
import net.java.sip.communicator.util.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The spell check dialog that would be opened from the right click menu in the
|
||||||
|
* chat window.
|
||||||
|
*
|
||||||
|
* @author Purvesh Sahoo
|
||||||
|
*/
|
||||||
|
public class SpellCheckerConfigDialog
|
||||||
|
extends SIPCommDialog
|
||||||
|
implements ActionListener
|
||||||
|
{
|
||||||
|
private static final Logger logger = Logger
|
||||||
|
.getLogger(SpellCheckerConfigDialog.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI Components
|
||||||
|
*/
|
||||||
|
private JTextComponent currentWord;
|
||||||
|
|
||||||
|
private JList suggestionList;
|
||||||
|
|
||||||
|
private JScrollPane suggestionScroll;
|
||||||
|
|
||||||
|
private JButton changeButton;
|
||||||
|
|
||||||
|
private JButton nextButton;
|
||||||
|
|
||||||
|
private JButton addButton;
|
||||||
|
|
||||||
|
private JPanel checkPanel;
|
||||||
|
|
||||||
|
private JPanel buttonsPanel;
|
||||||
|
|
||||||
|
private JPanel topPanel;
|
||||||
|
|
||||||
|
private JPanel suggestionPanel;
|
||||||
|
|
||||||
|
private SpellDictionary dict;
|
||||||
|
|
||||||
|
private Chat chat;
|
||||||
|
|
||||||
|
private final ResourceManagementService resources = Resources
|
||||||
|
.getResources();
|
||||||
|
|
||||||
|
private String word;
|
||||||
|
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
private Word clickedWord;
|
||||||
|
|
||||||
|
public SpellCheckerConfigDialog(Chat chat, Word clickedWord,
|
||||||
|
SpellDictionary dict)
|
||||||
|
{
|
||||||
|
|
||||||
|
super(false);
|
||||||
|
|
||||||
|
this.dict = dict;
|
||||||
|
this.chat = chat;
|
||||||
|
|
||||||
|
initComponents(clickedWord);
|
||||||
|
|
||||||
|
this.setTitle(resources.getI18NString("plugin.spellcheck.TITLE"));
|
||||||
|
this.setMinimumSize(new Dimension(450, 320));
|
||||||
|
this.setPreferredSize(new Dimension(450, 320));
|
||||||
|
this.setResizable(false);
|
||||||
|
|
||||||
|
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
||||||
|
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||||
|
|
||||||
|
mainPanel.add(topPanel);
|
||||||
|
|
||||||
|
this.getContentPane().add(mainPanel);
|
||||||
|
|
||||||
|
this.pack();
|
||||||
|
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||||
|
Dimension screenSize = toolkit.getScreenSize();
|
||||||
|
|
||||||
|
int x = (screenSize.width - this.getWidth()) / 2;
|
||||||
|
int y = (screenSize.height - this.getHeight()) / 2;
|
||||||
|
|
||||||
|
this.setLocation(x, y);
|
||||||
|
|
||||||
|
if (!currentWord.getText().equals(" ")
|
||||||
|
&& this.dict.isCorrect(currentWord.getText()))
|
||||||
|
{
|
||||||
|
nextButton.doClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialises the UI components.
|
||||||
|
*/
|
||||||
|
private void initComponents(final Word clickWord)
|
||||||
|
{
|
||||||
|
|
||||||
|
clickedWord =
|
||||||
|
(clickWord == null) ? Word.getWord(" ", 1, false) : clickWord;
|
||||||
|
|
||||||
|
topPanel = new TransparentPanel(new BorderLayout());
|
||||||
|
topPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
|
||||||
|
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
|
||||||
|
|
||||||
|
checkPanel = new TransparentPanel(new BorderLayout(10, 10));
|
||||||
|
checkPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
|
||||||
|
checkPanel.setLayout(new BoxLayout(checkPanel, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
currentWord = new JTextField(clickedWord.getText());
|
||||||
|
|
||||||
|
currentWord.setAlignmentX(LEFT_ALIGNMENT);
|
||||||
|
currentWord.setMaximumSize(new Dimension(550, 30));
|
||||||
|
|
||||||
|
currentWord.setText(clickedWord.getText());
|
||||||
|
currentWord.selectAll();
|
||||||
|
|
||||||
|
// JPanel wordPanel = new TransparentPanel(new BorderLayout());
|
||||||
|
// wordPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
|
||||||
|
// wordPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5));
|
||||||
|
// wordPanel.add(currentWord);
|
||||||
|
|
||||||
|
buttonsPanel =
|
||||||
|
new TransparentPanel(new FlowLayout(FlowLayout.RIGHT, 0, 10));
|
||||||
|
changeButton =
|
||||||
|
new JButton(
|
||||||
|
resources.getI18NString("plugin.spellcheck.dialog.REPLACE"));
|
||||||
|
changeButton.setMnemonic(resources
|
||||||
|
.getI18nMnemonic("plugin.spellcheck.dialog.REPLACE"));
|
||||||
|
|
||||||
|
changeButton.addActionListener(new ActionListener()
|
||||||
|
{
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (suggestionList.getSelectedValue() != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
StringBuffer newMessage =
|
||||||
|
new StringBuffer(chat.getMessage());
|
||||||
|
int endIndex;
|
||||||
|
|
||||||
|
if (word != null)
|
||||||
|
{
|
||||||
|
endIndex = index + currentWord.getText().length();
|
||||||
|
newMessage.replace(index, endIndex,
|
||||||
|
(String) suggestionList.getSelectedValue());
|
||||||
|
word = (String) suggestionList.getSelectedValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endIndex =
|
||||||
|
clickedWord.getStart()
|
||||||
|
+ clickedWord.getText().length();
|
||||||
|
newMessage.replace(clickedWord.getStart(), endIndex,
|
||||||
|
(String) suggestionList.getSelectedValue());
|
||||||
|
}
|
||||||
|
currentWord.setText((String) suggestionList
|
||||||
|
.getSelectedValue());
|
||||||
|
chat.setMessage(newMessage.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
changeButton.setEnabled(false);
|
||||||
|
|
||||||
|
nextButton =
|
||||||
|
new JButton(
|
||||||
|
resources.getI18NString("plugin.spellcheck.dialog.FIND"));
|
||||||
|
nextButton.setMnemonic(resources
|
||||||
|
.getI18nMnemonic("plugin.spellcheck.dialog.FIND"));
|
||||||
|
|
||||||
|
nextButton.addActionListener(new ActionListener()
|
||||||
|
{
|
||||||
|
|
||||||
|
public Word getNextWord()
|
||||||
|
{
|
||||||
|
|
||||||
|
Word nextWord;
|
||||||
|
int wordIndex;
|
||||||
|
|
||||||
|
if (word == null)
|
||||||
|
{
|
||||||
|
if (currentWord.getText().equals(" "))
|
||||||
|
{
|
||||||
|
String words[] = chat.getMessage().split(" ");
|
||||||
|
currentWord.setText(words[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
wordIndex =
|
||||||
|
chat.getMessage().indexOf(currentWord.getText());
|
||||||
|
if (dict.isCorrect(currentWord.getText()))
|
||||||
|
currentWord.setText("");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wordIndex = chat.getMessage().indexOf(word, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Word presentWord =
|
||||||
|
Word.getWord(chat.getMessage(), wordIndex, false);
|
||||||
|
|
||||||
|
if (presentWord.getEnd() == chat.getMessage().length())
|
||||||
|
{
|
||||||
|
nextWord = Word.getWord(chat.getMessage(), 1, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextWord =
|
||||||
|
Word.getWord(chat.getMessage(),
|
||||||
|
presentWord.getEnd() + 1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
index = nextWord.getStart();
|
||||||
|
word = nextWord.getText();
|
||||||
|
|
||||||
|
return nextWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
Word nextWord = getNextWord();
|
||||||
|
int breakIndex = nextWord.getStart();
|
||||||
|
|
||||||
|
while (dict.isCorrect(nextWord.getText())
|
||||||
|
&& nextWord.getEnd() + 1 != breakIndex)
|
||||||
|
{
|
||||||
|
nextWord = getNextWord();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dict.isCorrect(nextWord.getText()))
|
||||||
|
{
|
||||||
|
word = nextWord.getText();
|
||||||
|
currentWord.setText(nextWord.getText());
|
||||||
|
|
||||||
|
String clickedWord = currentWord.getText();
|
||||||
|
setSuggestionModel(clickedWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS));
|
||||||
|
buttonsPanel.add(changeButton);
|
||||||
|
buttonsPanel.add(nextButton);
|
||||||
|
|
||||||
|
checkPanel.add(currentWord, BorderLayout.NORTH);
|
||||||
|
checkPanel.add(Box.createHorizontalStrut(10));
|
||||||
|
checkPanel.add(buttonsPanel, BorderLayout.EAST);
|
||||||
|
|
||||||
|
topPanel.add(checkPanel, BorderLayout.NORTH);
|
||||||
|
topPanel.add(Box.createVerticalStrut(10));
|
||||||
|
|
||||||
|
DefaultListModel dataModel = new DefaultListModel();
|
||||||
|
suggestionList = new JList(dataModel);
|
||||||
|
|
||||||
|
suggestionScroll = new JScrollPane(suggestionList);
|
||||||
|
suggestionScroll.setAlignmentX(LEFT_ALIGNMENT);
|
||||||
|
|
||||||
|
if (!dict.isCorrect(clickedWord.getText()))
|
||||||
|
setSuggestionModel(clickedWord.getText());
|
||||||
|
|
||||||
|
suggestionList.addListSelectionListener(new ListSelectionListener()
|
||||||
|
{
|
||||||
|
|
||||||
|
public void valueChanged(ListSelectionEvent e)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!e.getValueIsAdjusting())
|
||||||
|
{
|
||||||
|
changeButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MouseListener clickListener = new MouseAdapter()
|
||||||
|
{
|
||||||
|
public void mouseClicked(MouseEvent e)
|
||||||
|
{
|
||||||
|
if (e.getClickCount() == 2)
|
||||||
|
{
|
||||||
|
|
||||||
|
StringBuffer newMessage =
|
||||||
|
new StringBuffer(chat.getMessage());
|
||||||
|
int endIndex;
|
||||||
|
|
||||||
|
if (word != null)
|
||||||
|
{
|
||||||
|
endIndex = index + currentWord.getText().length();
|
||||||
|
newMessage.replace(index, endIndex,
|
||||||
|
(String) suggestionList.getSelectedValue());
|
||||||
|
word = (String) suggestionList.getSelectedValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endIndex =
|
||||||
|
clickedWord.getStart()
|
||||||
|
+ clickedWord.getText().length();
|
||||||
|
newMessage.replace(clickedWord.getStart(), endIndex,
|
||||||
|
(String) suggestionList.getSelectedValue());
|
||||||
|
}
|
||||||
|
currentWord.setText((String) suggestionList
|
||||||
|
.getSelectedValue());
|
||||||
|
chat.setMessage(newMessage.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
suggestionList.addMouseListener(clickListener);
|
||||||
|
|
||||||
|
addButton =
|
||||||
|
new JButton(resources.getI18NString("plugin.spellcheck.dialog.ADD"));
|
||||||
|
addButton.setMnemonic(resources
|
||||||
|
.getI18nMnemonic("plugin.spellcheck.dialog.ADD"));
|
||||||
|
|
||||||
|
addButton.addActionListener(new ActionListener()
|
||||||
|
{
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dict.addWord(currentWord.getText());
|
||||||
|
chat.promptRepaint();
|
||||||
|
}
|
||||||
|
catch (SpellDictionaryException exc)
|
||||||
|
{
|
||||||
|
String msg = "Unable to add word to personal dictionary";
|
||||||
|
logger.error(msg, exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
suggestionPanel = new TransparentPanel(new BorderLayout(10, 10));
|
||||||
|
suggestionPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
|
||||||
|
suggestionPanel.setLayout(new BoxLayout(suggestionPanel,
|
||||||
|
BoxLayout.X_AXIS));
|
||||||
|
suggestionPanel.add(suggestionScroll);
|
||||||
|
suggestionPanel.add(Box.createHorizontalStrut(10));
|
||||||
|
suggestionPanel.add(addButton);
|
||||||
|
|
||||||
|
topPanel.add(suggestionPanel, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the model for the suggestion list
|
||||||
|
*
|
||||||
|
* @param clickedWord
|
||||||
|
*/
|
||||||
|
private void setSuggestionModel(String clickedWord)
|
||||||
|
{
|
||||||
|
|
||||||
|
DefaultListModel dataModel = new DefaultListModel();
|
||||||
|
List<String> corrections = this.dict.getSuggestions(clickedWord);
|
||||||
|
for (String correction : corrections)
|
||||||
|
{
|
||||||
|
dataModel.addElement(correction);
|
||||||
|
}
|
||||||
|
|
||||||
|
suggestionList.setModel(dataModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the selected correction value
|
||||||
|
*
|
||||||
|
* @return selected value from suggestion list
|
||||||
|
*/
|
||||||
|
public Object getCorrection()
|
||||||
|
{
|
||||||
|
|
||||||
|
return suggestionList.getSelectedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void close(boolean escaped)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in new issue