/**************************************************************************
OmegaT - Computer Assisted Translation (CAT) tool
with fuzzy matching, translation memory, keyword search,
glossaries, and translation leveraging into updated projects.
Copyright (C) 2011 Alex Buloichik
2012 Jean-Christophe Helary
2014 Aaron Madlon-Kay
Home page: http://www.omegat.org/
Support center: http://groups.yahoo.com/group/OmegaT/
This file is part of OmegaT.
OmegaT 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 3 of the License, or
(at your option) any later version.
OmegaT 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 <http://www.gnu.org/licenses/>.
**************************************************************************/
package org.omegat.gui.multtrans;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.text.JTextComponent;
import org.omegat.core.Core;
import org.omegat.core.data.SourceTextEntry;
import org.omegat.gui.common.EntryInfoThreadPane;
import org.omegat.gui.editor.IPopupMenuConstructor;
import org.omegat.gui.editor.SegmentBuilder;
import org.omegat.gui.main.DockableScrollPane;
import org.omegat.gui.main.IMainWindow;
import org.omegat.util.OStrings;
import org.omegat.util.Preferences;
import org.omegat.util.StringUtil;
import org.omegat.util.gui.IPaneMenu;
import org.omegat.util.gui.StaticUIUtils;
import org.omegat.util.gui.UIThreadsUtil;
/**
* Pane for display information about multiple translations.
*
* @author Alex Buloichik (alex73mail@gmail.com)
* @author Jean-Christophe Helary
* @author Aaron Madlon-Kay
*/
@SuppressWarnings("serial")
public class MultipleTransPane extends EntryInfoThreadPane<List<MultipleTransFoundEntry>> implements IPaneMenu {
private static final String EXPLANATION = OStrings.getString("GUI_MULTIPLETRANSLATIONSWINDOW_explanation");
private List<DisplayedEntry> entries = new ArrayList<DisplayedEntry>();
private final DockableScrollPane scrollPane;
public MultipleTransPane(IMainWindow mw) {
super(true);
String title = OStrings.getString("MULT_TITLE");
scrollPane = new DockableScrollPane("MULTIPLE_TRANS", title, this, true);
mw.addDockable(scrollPane);
setEditable(false);
StaticUIUtils.makeCaretAlwaysVisible(this);
setText(EXPLANATION);
setMinimumSize(new Dimension(100, 50));
Core.getEditor().registerPopupMenuConstructors(600, new IPopupMenuConstructor() {
public void addItems(JPopupMenu menu, JTextComponent comp, int mousepos, boolean isInActiveEntry,
boolean isInActiveTranslation, final SegmentBuilder sb) {
if (isInActiveEntry
&& Core.getProject().getProjectProperties().isSupportDefaultTranslations()) {
JMenuItem miDefault = menu.add(OStrings.getString("MULT_MENU_DEFAULT"));
JMenuItem miMultiple = menu.add(OStrings.getString("MULT_MENU_MULTIPLE"));
miDefault.setEnabled(!sb.isDefaultTranslation());
miMultiple.setEnabled(sb.isDefaultTranslation());
miDefault.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Core.getEditor().setAlternateTranslationForCurrentEntry(false);
Core.getEditor().commitAndLeave();
}
});
miMultiple.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Core.getEditor().setAlternateTranslationForCurrentEntry(true);
}
});
}
}
});
addMouseListener(mouseListener);
}
@Override
public void onEntryActivated(SourceTextEntry newEntry) {
scrollPane.stopNotifying();
super.onEntryActivated(newEntry);
}
@Override
protected void setFoundResult(SourceTextEntry processedEntry, List<MultipleTransFoundEntry> data) {
UIThreadsUtil.mustBeSwingThread();
clear();
// Check case if current segment has default translation and there are no alternative translations.
if (data.size() == 1 && data.get(0).key == null) {
return;
}
if (!data.isEmpty() && Preferences.isPreference(Preferences.NOTIFY_MULTIPLE_TRANSLATIONS)) {
scrollPane.notify(true);
}
StringBuilder o = new StringBuilder();
for (MultipleTransFoundEntry e : data) {
DisplayedEntry de = new DisplayedEntry();
de.entry = e;
de.start = o.length();
if (e.entry.translation == null) continue;
if (e.key != null) {
o.append(e.entry.translation).append('\n');
o.append('<').append(e.key.file);
if (e.key.id != null) {
o.append('/').append(e.key.id);
}
o.append(">\n");
if (e.key.prev != null && e.key.next != null) {
o.append('(').append(StringUtil.truncate(e.key.prev, 10));
o.append(" <...> ").append(StringUtil.truncate(e.key.next, 10)).append(")\n");
}
} else {
o.append(e.entry.translation).append('\n');
}
de.end = o.length();
entries.add(de);
o.append('\n');
}
setText(o.toString());
}
@Override
public void clear() {
super.clear();
entries.clear();
}
@Override
protected void onProjectOpen() {
UIThreadsUtil.mustBeSwingThread();
clear();
}
@Override
protected void onProjectClose() {
UIThreadsUtil.mustBeSwingThread();
clear();
setText(EXPLANATION);
}
@Override
protected void startSearchThread(SourceTextEntry newEntry) {
new MultipleTransFindThread(this, Core.getProject(), newEntry).start();
}
private DisplayedEntry getEntryAtPosition(int pos) {
for (DisplayedEntry de : entries) {
if (de.start <= pos && de.end >= pos) {
return de;
}
}
return null;
}
protected final transient MouseListener mouseListener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger()) {
doPopup(e.getPoint());
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
doPopup(e.getPoint());
}
}
private void doPopup(Point p) {
if (entries.isEmpty()) {
return;
}
JPopupMenu popup = new JPopupMenu();
populateContextMenu(popup, viewToModel(p));
popup.show(MultipleTransPane.this, p.x, p.y);
}
};
private void populateContextMenu(JPopupMenu popup, int pos) {
final DisplayedEntry de = getEntryAtPosition(pos);
JMenuItem item;
// default translation
item = popup.add(OStrings.getString("MULT_POPUP_DEFAULT"));
item.setEnabled(de != null && de.entry.key != null);
if (de != null && de.entry.key != null) {
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Core.getEditor().replaceEditText(de.entry.entry.translation);
Core.getEditor().setAlternateTranslationForCurrentEntry(false);
Core.getEditor().commitAndLeave();
}
});
}
// non-default translation
item = popup.add(OStrings.getString("MULT_POPUP_REPLACE"));
item.setEnabled(de != null);
if (de != null) {
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Core.getEditor().replaceEditText(de.entry.entry.translation);
}
});
}
item = popup.add(OStrings.getString("MULT_POPUP_GOTO"));
item.setEnabled(de != null);
if (de != null) {
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Core.getEditor().gotoEntry(de.entry.sourceText, de.entry.key);
}
});
}
}
protected static class DisplayedEntry {
int start, end;
MultipleTransFoundEntry entry;
}
@Override
public void populatePaneMenu(JPopupMenu menu) {
//populateContextMenu(menu, getCaretPosition());
//menu.addSeparator();
final JMenuItem notify = new JCheckBoxMenuItem(OStrings.getString("MULT_SETTINGS_NOTIFY"));
notify.setSelected(Preferences.isPreference(Preferences.NOTIFY_MULTIPLE_TRANSLATIONS));
notify.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Preferences.setPreference(Preferences.NOTIFY_MULTIPLE_TRANSLATIONS, notify.isSelected());
}
});
menu.add(notify);
}
}