package ro.nextreports.designer.i18n.action;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
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.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.swing.AbstractListModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import org.jdesktop.swingx.JXList;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.JXTitledSeparator;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.HighlightPredicate;
import ro.nextreports.designer.util.I18NSupport;
import ro.nextreports.designer.util.ImageUtil;
import ro.nextreports.designer.util.Show;
import ro.nextreports.designer.Globals;
import ro.nextreports.engine.i18n.I18nLanguage;
import ro.nextreports.engine.i18n.I18nString;
public class ManageI18nPanel extends JPanel {
private JXList keysList;
private SortedListModel<String> keysModel;
private JButton keyAddButton;
private JButton keyEditButton;
private JButton keyRemoveButton;
private JXList languagesList;
private DefaultListModel languagesModel;
private JButton languageAddButton;
private JButton languageEditButton;
private JButton languageRemoveButton;
private JXTable table;
private KeysTableModel model;
private JButton langKeyEditButton;
public ManageI18nPanel() {
super();
Dimension buttonDim = new Dimension(20, 20);
keysList = new JXList();
keysList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent event) {
if (event.getClickCount() == 2) {
modifyKey();
}
}
});
keysModel = new SortedListModel<String>();
JScrollPane scroll = new JScrollPane();
scroll.setPreferredSize(new Dimension(200, 110));
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scroll.getViewport().add(keysList, null);
keysList.setModel(keysModel);
keyAddButton = new JButton(ImageUtil.getImageIcon("add"));
keyAddButton.setToolTipText(I18NSupport.getString("languages.keys.add"));
keyAddButton.setPreferredSize(buttonDim);
keyAddButton.setMinimumSize(buttonDim);
keyAddButton.setMaximumSize(buttonDim);
keyAddButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
addKey();
}
});
keyEditButton = new JButton(ImageUtil.getImageIcon("edit"));
keyEditButton.setToolTipText(I18NSupport.getString("languages.keys.edit"));
keyEditButton.setPreferredSize(buttonDim);
keyEditButton.setMinimumSize(buttonDim);
keyEditButton.setMaximumSize(buttonDim);
keyEditButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
modifyKey();
}
});
keyRemoveButton = new JButton(ImageUtil.getImageIcon("clear"));
keyRemoveButton.setToolTipText(I18NSupport.getString("languages.keys.remove"));
keyRemoveButton.setPreferredSize(buttonDim);
keyRemoveButton.setMinimumSize(buttonDim);
keyRemoveButton.setMaximumSize(buttonDim);
keyRemoveButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
removeKeys();
}
});
languagesList = new JXList();
languagesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
languagesList.setCellRenderer(new LanguageCellRenderer());
languagesList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
int index = languagesList.getSelectedIndex();
if (index >= 0) {
I18nLanguage language = (I18nLanguage) languagesModel.getElementAt(index);
model.clear();
for (I18nString s : language.getI18nStrings()) {
model.addObject(s);
}
}
}
});
languagesModel = new DefaultListModel();
JScrollPane scroll2 = new JScrollPane();
scroll2.setPreferredSize(new Dimension(200, 40));
scroll2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scroll2.getViewport().add(languagesList, null);
languagesList.setModel(languagesModel);
languageAddButton = new JButton(ImageUtil.getImageIcon("add"));
languageAddButton.setToolTipText(I18NSupport.getString("languages.add"));
languageAddButton.setPreferredSize(buttonDim);
languageAddButton.setMinimumSize(buttonDim);
languageAddButton.setMaximumSize(buttonDim);
languageAddButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
addLanguage();
}
});
languageEditButton = new JButton(ImageUtil.getImageIcon("edit"));
languageEditButton.setToolTipText(I18NSupport.getString("languages.edit"));
languageEditButton.setPreferredSize(buttonDim);
languageEditButton.setMinimumSize(buttonDim);
languageEditButton.setMaximumSize(buttonDim);
languageEditButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
modifyLanguage();
}
});
languageRemoveButton = new JButton(ImageUtil.getImageIcon("clear"));
languageRemoveButton.setToolTipText(I18NSupport.getString("languages.remove"));
languageRemoveButton.setPreferredSize(buttonDim);
languageRemoveButton.setMinimumSize(buttonDim);
languageRemoveButton.setMaximumSize(buttonDim);
languageRemoveButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
removeLanguages();
}
});
model = new KeysTableModel();
table = new JXTable(model);
table.setSortable(false);
table.setRolloverEnabled(true);
table.addHighlighter(new ColorHighlighter(HighlightPredicate.ROLLOVER_ROW, null, Color.RED));
table.setPreferredScrollableViewportSize(new Dimension(200, 200));
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent event) {
if (event.getClickCount() == 2) {
modifyLanguageKey();
}
}
});
langKeyEditButton = new JButton(ImageUtil.getImageIcon("edit"));
langKeyEditButton.setToolTipText(I18NSupport.getString("languages.keys.edit"));
langKeyEditButton.setPreferredSize(buttonDim);
langKeyEditButton.setMinimumSize(buttonDim);
langKeyEditButton.setMaximumSize(buttonDim);
langKeyEditButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
modifyLanguageKey();
}
});
this.setLayout(new GridBagLayout());
JPanel keysPanel = new JPanel();
keysPanel.setLayout(new GridBagLayout());
keysPanel.add(new JXTitledSeparator(I18NSupport.getString("languages.keys")), new GridBagConstraints(0, 0, 2, 1, 1.0,
0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
keysPanel.add(scroll, new GridBagConstraints(0, 1, 1, 3, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
new Insets(5, 0, 0, 5), 0, 0));
keysPanel.add(keyAddButton, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(5, 2, 5, 5), 0, 0));
keysPanel.add(keyEditButton, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(0, 2, 5, 5), 0, 0));
keysPanel.add(keyRemoveButton, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(0, 2, 5, 5), 0, 0));
JPanel languagesPanel = new JPanel();
languagesPanel.setLayout(new GridBagLayout());
languagesPanel.add(new JXTitledSeparator(I18NSupport.getString("languages")), new GridBagConstraints(0, 0, 2, 1, 1.0,
0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
languagesPanel.add(scroll2, new GridBagConstraints(0, 1, 1, 3, 1.0, 1.0, GridBagConstraints.WEST,
GridBagConstraints.BOTH, new Insets(5, 0, 0, 5), 0, 0));
languagesPanel.add(languageAddButton, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(5, 2, 5, 5), 0, 0));
languagesPanel.add(languageEditButton, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(0, 2, 5, 5), 0, 0));
languagesPanel.add(languageRemoveButton, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(0, 2, 5, 5), 0, 0));
JPanel kPanel = new JPanel();
kPanel.setLayout(new GridBagLayout());
JScrollPane scroll3 = new JScrollPane(table);
scroll3.setPreferredSize(new Dimension(200, 150));
kPanel.add(scroll3, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
new Insets(5, 0, 0, 5), 0, 0));
kPanel.add(langKeyEditButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(5, 2, 5, 5), 0, 0));
add(keysPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(
0, 0, 0, 0), 0, 0));
add(languagesPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.1, GridBagConstraints.WEST, GridBagConstraints.BOTH,
new Insets(5, 0, 0, 0), 0, 0));
add(kPanel, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(5,
0, 0, 0), 0, 0));
}
private void addKey() {
KeySelectionPanel panel = new KeySelectionPanel(false);
KeySelectionDialog dialog = new KeySelectionDialog(panel, false);
dialog.pack();
Show.centrateComponent(Globals.getMainFrame(), dialog);
dialog.setVisible(true);
if (dialog.okPressed()) {
List<String> keys = panel.getKeys();
for (String key : keys) {
if (!keysModel.contains(key)) {
addKey(key);
} else {
// Show.info(I18NSupport.getString("languages.keys.selection.key.exists"));
}
}
I18nManager.getInstance().addKeys(keys);
}
}
private void modifyKey() {
if ((keysList.getSelectedValue() == null) || (keysList.getSelectedValues().length > 1)) {
Show.info(I18NSupport.getString("languages.keys.selection.key.invalid"));
return;
}
KeySelectionPanel panel = new KeySelectionPanel(false);
panel.setKey((String) keysList.getSelectedValue());
KeySelectionDialog dialog = new KeySelectionDialog(panel, true);
dialog.pack();
Show.centrateComponent(Globals.getMainFrame(), dialog);
dialog.setVisible(true);
if (dialog.okPressed()) {
int index = keysList.getSelectedIndex();
String key = panel.getKey();
editKey(index, key);
I18nManager.getInstance().setKeys(keysModel.toList());
}
}
private void removeKeys() {
int[] indices = keysList.getSelectedIndices();
for (int i = indices.length - 1; i >= 0; i--) {
deleteKey(indices[i]);
}
I18nManager.getInstance().setKeys(keysModel.toList());
}
private void addLanguage() {
LanguageSelectionPanel panel = new LanguageSelectionPanel();
LanguageSelectionDialog dialog = new LanguageSelectionDialog(getLanguages(), panel, false);
dialog.pack();
Show.centrateComponent(Globals.getMainFrame(), dialog);
dialog.setVisible(true);
if (dialog.okPressed()) {
I18nLanguage language = panel.getLanguage();
List<I18nString> strings = new ArrayList<I18nString>();
for (String key : keysModel.toList()) {
strings.add(new I18nString(key, ""));
}
language.setI18nStrings(strings);
if (!languagesModel.contains(language)) {
languagesModel.addElement(language);
I18nManager.getInstance().addLanguage(language);
} else {
Show.info(I18NSupport.getString("languages.keys.selection.key.exists"));
}
}
}
private void modifyLanguage() {
if (languagesList.getSelectedValue() == null) {
Show.info(I18NSupport.getString("languages.invalid"));
return;
}
// LanguageSelectionPanel panel = new LanguageSelectionPanel();
// panel.setLanguage((I18nLanguage)languagesList.getSelectedValue());
// LanguageSelectionDialog dialog = new
// LanguageSelectionDialog(getLanguages(), panel, true);
//
// dialog.pack();
// Show.centrateComponent(Globals.getMainFrame(), dialog);
// dialog.setVisible(true);
// if (dialog.okPressed()) {
// int index = languagesList.getSelectedIndex();
// I18nLanguage oldLanguage =
// (I18nLanguage)languagesList.getElementAt(index);
// I18nLanguage language = panel.getLanguage();
// language.setI18nStrings(oldLanguage.getI18nStrings());
// languagesModel.set(index,language);
// }
int index = languagesList.getSelectedIndex();
for (int i = 0, size = languagesModel.size(); i < size; i++) {
I18nLanguage language = (I18nLanguage) languagesModel.get(i);
if (i == index) {
language.setDefault(true);
I18nManager.getInstance().setCurrentLanguage(language);
} else {
language.setDefault(false);
}
languagesModel.set(i, language);
}
}
private void removeLanguages() {
int[] indices = languagesList.getSelectedIndices();
System.out.println("----- " +indices.length + " " + indices[0]);
for (int i = indices.length - 1; i >= 0; i--) {
System.out.println(" remove index = " + indices[i]);
languagesModel.removeElementAt(indices[i]);
}
}
private void modifyLanguageKey() {
KeySelectionPanel panel = new KeySelectionPanel(true);
int[] selectedRows = table.getSelectedRows();
if (selectedRows.length == 0) {
Show.info(I18NSupport.getString("languages.keys.selection.key.invalid"));
return;
}
int stringIndex = selectedRows[0];
I18nString oldString = (I18nString) model.getObjectForRow(stringIndex);
panel.setKey(oldString.getKey());
panel.setValue(oldString.getValue());
KeySelectionDialog dialog = new KeySelectionDialog(panel, true);
dialog.pack();
Show.centrateComponent(Globals.getMainFrame(), dialog);
dialog.setVisible(true);
if (dialog.okPressed()) {
int languageIndex = languagesList.getSelectedIndex();
String value = panel.getValue();
I18nString newString = new I18nString(oldString.getKey(), value);
I18nManager.getInstance().getLanguages().get(languageIndex).getI18nStrings().set(stringIndex, newString);
model.updateObject(stringIndex, newString);
}
}
public List<String> getKeys() {
List<String> result = keysModel.toList();
// Collections.sort(result, new Comparator<String>() {
//
// @Override
// public int compare(String o1, String o2) {
// return Collator.getInstance().compare(o1, o2);
// }
// });
return result;
}
public List<I18nLanguage> getLanguages() {
List<I18nLanguage> result = new ArrayList<I18nLanguage>();
for (Object obj : languagesModel.toArray()) {
result.add((I18nLanguage) obj);
}
return result;
}
public void setKeys(List<String> keys) {
I18nManager.getInstance().setKeys(keys);
keysModel.clear();
for (String s : keys) {
keysModel.add(s);
}
}
public void setLanguages(List<I18nLanguage> languages) {
I18nManager.getInstance().setLanguages(languages);
languagesModel.clear();
for (I18nLanguage language : languages) {
languagesModel.addElement(language);
}
languagesList.setSelectedIndex(0);
}
class LanguageCellRenderer extends JLabel implements ListCellRenderer {
public LanguageCellRenderer() {
setOpaque(true);
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
I18nLanguage language = (I18nLanguage) value;
StringBuilder sb = new StringBuilder(language.getName());
if (language.isDefault()) {
sb.append(" (").append(I18NSupport.getString("languages.default")).append(")");
}
setText(sb.toString());
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
return this;
}
}
public class KeysTableModel extends AbstractTableModel {
private final String[] columnNames = { I18NSupport.getString("languages.keys.selection.key"),
I18NSupport.getString("languages.keys.selection.value") };
private SortedSet elements = new TreeSet();
public String getColumnName(int columnIndex) {
return columnNames[columnIndex];
}
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
// this method is called in the constructor so we must test for null
if (elements == null) {
return 0;
}
return elements.size();
}
@SuppressWarnings("unchecked")
public void addObject(Object object) {
elements.add(object);
fireTableDataChanged();
}
public boolean containsObject(Object object) {
return (elements.contains(object));
}
@SuppressWarnings("unchecked")
public void addObjects(List objects) {
elements.addAll(objects);
fireTableDataChanged();
}
public void deleteObject(int rowIndex) {
elements.remove(getObjectForRow(rowIndex));
fireTableDataChanged();
}
@SuppressWarnings("unchecked")
public void deleteObjects(List objects) {
elements.removeAll(objects);
fireTableDataChanged();
}
public void clear() {
elements.clear();
fireTableDataChanged();
}
public Object getObjectForRow(int rowIndex) {
return elements.toArray()[rowIndex];
}
public Object set(int index, Object element) {
Object oldElement = getObjectForRow(index);
elements.remove(oldElement);
addObject(element);
return oldElement;
}
@SuppressWarnings("unchecked")
public void updateObject(int row, Object object) {
row = table.convertRowIndexToModel(row);
set(row, object);
fireTableDataChanged();
}
public Object getValueAt(int rowIndex, int columnIndex) {
I18nString row = (I18nString)getObjectForRow(rowIndex);
switch (columnIndex) {
case 0:
return row.getKey();
case 1:
return row.getValue();
default:
return null;
}
}
}
public void addKey(String key) {
keysModel.add(key);
for (I18nLanguage language : I18nManager.getInstance().getLanguages()) {
boolean found = false;
for (I18nString s : language.getI18nStrings()) {
if (s.getKey().equals(key)) {
found = true;
break;
}
}
if (!found) {
I18nString s = new I18nString(key, "");
language.getI18nStrings().add(s);
if (!model.containsObject(s)) {
model.addObject(s);
}
}
}
}
public void editKey(int index, String key) {
String oldKey = (String) keysModel.set(index, key);
for (I18nLanguage language : I18nManager.getInstance().getLanguages()) {
List<I18nString> strings = language.getI18nStrings();
for (int i = 0, size = strings.size(); i < size; i++) {
I18nString s = (I18nString) strings.get(i);
if (s.getKey().equals(oldKey)) {
String value = s.getValue();
s = new I18nString(key, value);
strings.set(i, s);
model.updateObject(index, s);
}
}
}
}
public void deleteKey(int index) {
String key = (String) keysModel.getElementAt(index);
keysModel.removeElementAt(index);
for (I18nLanguage language : I18nManager.getInstance().getLanguages()) {
for (Iterator it = language.getI18nStrings().iterator(); it.hasNext();) {
I18nString s = (I18nString) it.next();
if (s.getKey().equals(key)) {
it.remove();
if (model.getRowCount() > index) {
model.deleteObject(index);
}
break;
}
}
}
}
private class SortedListModel<T> extends AbstractListModel {
private SortedSet<T> model;
public SortedListModel() {
model = new TreeSet<T>();
}
public int getSize() {
return model.size();
}
@SuppressWarnings("unchecked")
public T getElementAt(int index) {
return (T) model.toArray()[index];
}
public void add(T element) {
if (model.add(element)) {
fireContentsChanged(this, 0, getSize());
}
}
public void addAll(T[] elements) {
Collection<T> c = Arrays.asList(elements);
model.addAll(c);
fireContentsChanged(this, 0, getSize());
}
public void clear() {
model.clear();
fireContentsChanged(this, 0, getSize());
}
public boolean contains(T element) {
return model.contains(element);
}
public T firstElement() {
return model.first();
}
public Iterator<T> iterator() {
return model.iterator();
}
public T lastElement() {
return model.last();
}
public boolean removeElement(T element) {
boolean removed = model.remove(element);
if (removed) {
fireContentsChanged(this, 0, getSize());
}
return removed;
}
public boolean removeElementAt(int index) {
T element = getElementAt(index);
boolean removed = model.remove(element);
if (removed) {
fireContentsChanged(this, 0, getSize());
}
return removed;
}
public T set(int index, T element) {
T oldElement = getElementAt(index);
removeElement(oldElement);
add(element);
return oldElement;
}
public List<T> toList() {
return new LinkedList<T>(model);
}
}
}