/* LanguageTool, a natural language style checker
* Copyright (C) 2007 Daniel Naber (http://www.danielnaber.de)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA
*/
package org.languagetool.gui;
import java.awt.Container;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.filechooser.FileFilter;
import org.languagetool.JLanguageTool;
import org.languagetool.Language;
import org.languagetool.language.LanguageBuilder;
/**
* Dialog for managing externally loaded rules.
*
* @author Daniel Naber
*/
public class LanguageManagerDialog implements ActionListener {
private final List<File> ruleFiles = new ArrayList<>();
private final Frame owner;
private final ResourceBundle messages;
private JDialog dialog;
private JList<File> list;
private JButton addButton;
private JButton removeButton;
private JButton closeButton;
public LanguageManagerDialog(Frame owner, List<Language> languages) {
this.owner = owner;
for (Language lang : languages) {
for (final String ruleFile : lang.getRuleFileNames()) {
ruleFiles.add(new File(ruleFile));
}
}
messages = JLanguageTool.getMessageBundle();
}
public void show() {
dialog = new JDialog(owner, true);
dialog.setTitle(messages.getString("guiLanguageManagerDialog"));
// close dialog when user presses Escape key:
// TODO: taken from ConfigurationDialog, avoid duplication:
final KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
final ActionListener actionListener = new ActionListener() {
@Override
@SuppressWarnings("unused")
public void actionPerformed(ActionEvent actionEvent) {
dialog.setVisible(false);
}
};
final JRootPane rootPane = dialog.getRootPane();
rootPane.registerKeyboardAction(actionListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
final Container contentPane = dialog.getContentPane();
contentPane.setLayout(new GridBagLayout());
list = new JList<>(ruleFiles.toArray(new File[ruleFiles.size()]));
GridBagConstraints cons = new GridBagConstraints();
cons.insets = new Insets(4, 4, 4, 4);
cons.gridx = 0;
cons.gridy = 0;
cons.fill = GridBagConstraints.BOTH;
cons.weightx = 2.0f;
cons.weighty = 2.0f;
contentPane.add(new JScrollPane(list), cons);
cons = new GridBagConstraints();
cons.insets = new Insets(4, 4, 4, 4);
cons.fill = GridBagConstraints.HORIZONTAL;
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridBagLayout());
addButton = new JButton(messages.getString("guiAddButton"));
addButton.addActionListener(this);
cons.gridx = 1;
cons.gridy = 0;
buttonPanel.add(addButton, cons);
removeButton = new JButton(messages.getString("guiRemoveButton"));
removeButton.addActionListener(this);
cons.gridx = 1;
cons.gridy = 1;
buttonPanel.add(removeButton, cons);
closeButton = new JButton(messages.getString("guiCloseButton"));
closeButton.addActionListener(this);
cons.gridx = 1;
cons.gridy = 2;
buttonPanel.add(closeButton, cons);
cons.gridx = 1;
cons.gridy = 0;
cons = new GridBagConstraints();
cons.anchor = GridBagConstraints.NORTH;
contentPane.add(buttonPanel, cons);
dialog.pack();
dialog.setSize(300, 200);
dialog.setLocationByPlatform(true);
dialog.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == addButton) {
Configuration config = null;
try {
config = new Configuration(null);
} catch (IOException e1) {
throw new RuntimeException(e1);
}
File initialDir;
File ruleFile;
if (config.getExternalRuleDirectory() != null) {
initialDir = new File(config.getExternalRuleDirectory());
if (initialDir.isDirectory()) {
ruleFile = Tools.openFileDialog(owner, new XMLFileFilter(), initialDir);
} else {
ruleFile = Tools.openFileDialog(owner, new XMLFileFilter());
}
} else {
ruleFile = Tools.openFileDialog(owner, new XMLFileFilter());
}
if (ruleFile == null) {
return; // dialog was canceled
}
if (config != null) {
config.setExternalRuleDirectory(ruleFile.getParent());
try {
config.saveConfiguration(null);
} catch (IOException e1) {
throw new RuntimeException(e1);
}
}
if (!ruleFiles.contains(ruleFile)) {
ruleFiles.add(ruleFile);
list.setListData(ruleFiles.toArray(new File[ruleFiles.size()]));
} else {
final JOptionPane jop = new JOptionPane();
JOptionPane.showMessageDialog(jop, messages.getString("guiDuplicate"),
messages.getString("guiWarning"), JOptionPane.WARNING_MESSAGE);
}
} else if (e.getSource() == removeButton) {
if (list.getSelectedIndex() != -1) {
ruleFiles.remove(list.getSelectedIndex());
list.setListData(ruleFiles.toArray(new File[ruleFiles.size()]));
}
} else if (e.getSource() == closeButton) {
dialog.setVisible(false);
} else {
throw new IllegalArgumentException("Don't know how to handle " + e);
}
}
/**
* Return all external Languages.
*/
List<Language> getLanguages() throws IllegalAccessException, InstantiationException {
final List<Language> languages = new ArrayList<>();
for (File ruleFile : ruleFiles) {
if (ruleFile != null) {
final Language newLanguage = LanguageBuilder.makeAdditionalLanguage(ruleFile);
languages.add(newLanguage);
}
}
return languages;
}
static class XMLFileFilter extends FileFilter {
@Override
public boolean accept(final File f) {
if (f.getName().startsWith("rules") && f.getName().toLowerCase().endsWith(".xml")
|| f.isDirectory()) {
return true;
}
return false;
}
@Override
public String getDescription() {
return "rules*.xml";
}
}
}