feat: Adds progress dialog for translations and logic for pre-selecting empty languages

This commit is contained in:
lantzelot-swe 2021-02-04 22:41:34 +01:00
parent a6a093b8db
commit b7d8c529b4
6 changed files with 376 additions and 193 deletions

View File

@ -22,6 +22,9 @@ import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import se.lantz.gui.translation.TranslationDialog;
import se.lantz.gui.translation.TranslationProgressDialog;
import se.lantz.gui.translation.TranslationWorker;
import se.lantz.model.InfoModel;
import se.lantz.util.DescriptionTranslater;
@ -427,10 +430,12 @@ public class InfoPanel extends JPanel
dialog.setLocationRelativeTo(translateButton);
if (dialog.showDialog())
{
//Update model with translated text
String fromLanguage = dialog.getSelectedFromLanguage();
List<String> toLanguagesList = dialog.getSelectedToLanguages();
model.translateDescription(fromLanguage, toLanguagesList);
TranslationProgressDialog progressDialog = new TranslationProgressDialog(MainWindow.getInstance());
progressDialog.pack();
progressDialog.setLocationRelativeTo(MainWindow.getInstance());
TranslationWorker worker = new TranslationWorker(model, progressDialog, dialog.getSelectedFromLanguage(), dialog.getSelectedToLanguages());
worker.execute();
progressDialog.setVisible(true);
}
}
});

View File

@ -1,7 +1,9 @@
package se.lantz.gui;
package se.lantz.gui.translation;
import java.util.List;
import se.lantz.gui.BaseDialog;
import se.lantz.gui.MainWindow;
import se.lantz.model.InfoModel;
public class TranslationDialog extends BaseDialog
@ -18,19 +20,21 @@ public class TranslationDialog extends BaseDialog
this.setResizable(false);
}
private TranslationPanel getTranslationPanel() {
if (panel == null) {
panel = new TranslationPanel(model);
private TranslationPanel getTranslationPanel()
{
if (panel == null)
{
panel = new TranslationPanel(model);
}
return panel;
}
String getSelectedFromLanguage()
public String getSelectedFromLanguage()
{
return getTranslationPanel().getSelectedFromLanguage();
}
List<String> getSelectedToLanguages()
public List<String> getSelectedToLanguages()
{
return getTranslationPanel().getSelectedToLanguages();
}

View File

@ -1,21 +1,19 @@
package se.lantz.gui;
package se.lantz.gui.translation;
import java.awt.LayoutManager;
import javax.swing.JPanel;
import se.lantz.model.InfoModel;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JComboBox;
import javax.swing.JCheckBox;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.awt.event.ActionEvent;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import se.lantz.model.InfoModel;
public class TranslationPanel extends JPanel
{
@ -25,7 +23,7 @@ public class TranslationPanel extends JPanel
private static final String ES = "Spanish (es)";
private static final String IT = "Italian (it)";
private JLabel selectFromLabel;
private JComboBox fromComboBox;
private JComboBox<String> fromComboBox;
private JLabel toLanguageLabel;
private JPanel checkBoxPanel;
private JCheckBox enCheckBox;
@ -42,18 +40,17 @@ public class TranslationPanel extends JPanel
setLayout(gridBagLayout);
GridBagConstraints gbc_selectFromLabel = new GridBagConstraints();
gbc_selectFromLabel.anchor = GridBagConstraints.WEST;
gbc_selectFromLabel.insets = new Insets(10, 5, 5, 5);
gbc_selectFromLabel.insets = new Insets(10, 10, 5, 5);
gbc_selectFromLabel.gridx = 0;
gbc_selectFromLabel.gridy = 0;
add(getSelectFromLabel(), gbc_selectFromLabel);
GridBagConstraints gbc_fromComboBox = new GridBagConstraints();
gbc_fromComboBox.anchor = GridBagConstraints.WEST;
gbc_fromComboBox.insets = new Insets(10, 0, 5, 0);
gbc_fromComboBox.insets = new Insets(10, 0, 5, 10);
gbc_fromComboBox.gridx = 1;
gbc_fromComboBox.gridy = 0;
add(getFromComboBox(), gbc_fromComboBox);
GridBagConstraints gbc_toLanguageLabel = new GridBagConstraints();
gbc_toLanguageLabel.anchor = GridBagConstraints.WEST;
gbc_toLanguageLabel.gridwidth = 2;
gbc_toLanguageLabel.insets = new Insets(5, 5, 5, 0);
gbc_toLanguageLabel.gridx = 0;
@ -68,109 +65,139 @@ public class TranslationPanel extends JPanel
gbc_checkBoxPanel.gridx = 0;
gbc_checkBoxPanel.gridy = 2;
add(getCheckBoxPanel(), gbc_checkBoxPanel);
// TODO Auto-generated constructor stub
}
private JLabel getSelectFromLabel() {
if (selectFromLabel == null) {
selectFromLabel = new JLabel("Select language to generate translations from: ");
private JLabel getSelectFromLabel()
{
if (selectFromLabel == null)
{
selectFromLabel = new JLabel("Select language to generate translation from:");
}
return selectFromLabel;
}
private JComboBox getFromComboBox() {
if (fromComboBox == null) {
fromComboBox = new JComboBox();
fromComboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
enableCheckBoxes();
}
});
fromComboBox.addItem(EN);
fromComboBox.addItem(DE);
fromComboBox.addItem(FR);
fromComboBox.addItem(ES);
fromComboBox.addItem(IT);
private JComboBox<String> getFromComboBox()
{
if (fromComboBox == null)
{
fromComboBox = new JComboBox<>();
fromComboBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
enableCheckBoxes();
}
});
fromComboBox.addItem(EN);
fromComboBox.addItem(DE);
fromComboBox.addItem(FR);
fromComboBox.addItem(ES);
fromComboBox.addItem(IT);
}
return fromComboBox;
}
private JLabel getToLanguageLabel() {
if (toLanguageLabel == null) {
toLanguageLabel = new JLabel("Generate translations for the following languages:");
private JLabel getToLanguageLabel()
{
if (toLanguageLabel == null)
{
toLanguageLabel = new JLabel("Generate translations for the following languages:");
}
return toLanguageLabel;
}
private JPanel getCheckBoxPanel() {
if (checkBoxPanel == null) {
checkBoxPanel = new JPanel();
GridBagLayout gbl_checkBoxPanel = new GridBagLayout();
gbl_checkBoxPanel.columnWidths = new int[]{0, 0};
gbl_checkBoxPanel.rowHeights = new int[]{0, 0, 0, 0, 0, 0};
gbl_checkBoxPanel.columnWeights = new double[]{0.0, Double.MIN_VALUE};
gbl_checkBoxPanel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
checkBoxPanel.setLayout(gbl_checkBoxPanel);
GridBagConstraints gbc_enCheckBox = new GridBagConstraints();
gbc_enCheckBox.insets = new Insets(0, 5, 5, 0);
gbc_enCheckBox.anchor = GridBagConstraints.WEST;
gbc_enCheckBox.gridx = 0;
gbc_enCheckBox.gridy = 0;
checkBoxPanel.add(getEnCheckBox(), gbc_enCheckBox);
GridBagConstraints gbc_deCheckBox = new GridBagConstraints();
gbc_deCheckBox.anchor = GridBagConstraints.WEST;
gbc_deCheckBox.insets = new Insets(0, 5, 5, 0);
gbc_deCheckBox.gridx = 0;
gbc_deCheckBox.gridy = 1;
checkBoxPanel.add(getDeCheckBox(), gbc_deCheckBox);
GridBagConstraints gbc_frCheckBox = new GridBagConstraints();
gbc_frCheckBox.anchor = GridBagConstraints.WEST;
gbc_frCheckBox.insets = new Insets(0, 5, 5, 0);
gbc_frCheckBox.gridx = 0;
gbc_frCheckBox.gridy = 2;
checkBoxPanel.add(getFrCheckBox(), gbc_frCheckBox);
GridBagConstraints gbc_esCheckBox = new GridBagConstraints();
gbc_esCheckBox.anchor = GridBagConstraints.WEST;
gbc_esCheckBox.insets = new Insets(0, 5, 5, 0);
gbc_esCheckBox.gridx = 0;
gbc_esCheckBox.gridy = 3;
checkBoxPanel.add(getEsCheckBox(), gbc_esCheckBox);
GridBagConstraints gbc_itCheckBox = new GridBagConstraints();
gbc_itCheckBox.anchor = GridBagConstraints.WEST;
gbc_itCheckBox.insets = new Insets(0, 5, 0, 0);
gbc_itCheckBox.gridx = 0;
gbc_itCheckBox.gridy = 4;
checkBoxPanel.add(getItCheckBox(), gbc_itCheckBox);
private JPanel getCheckBoxPanel()
{
if (checkBoxPanel == null)
{
checkBoxPanel = new JPanel();
GridBagLayout gbl_checkBoxPanel = new GridBagLayout();
checkBoxPanel.setLayout(gbl_checkBoxPanel);
GridBagConstraints gbc_enCheckBox = new GridBagConstraints();
gbc_enCheckBox.anchor = GridBagConstraints.WEST;
gbc_enCheckBox.insets = new Insets(0, 5, 5, 0);
gbc_enCheckBox.gridx = 0;
gbc_enCheckBox.gridy = 0;
checkBoxPanel.add(getEnCheckBox(), gbc_enCheckBox);
GridBagConstraints gbc_deCheckBox = new GridBagConstraints();
gbc_deCheckBox.anchor = GridBagConstraints.WEST;
gbc_deCheckBox.insets = new Insets(0, 5, 5, 0);
gbc_deCheckBox.gridx = 0;
gbc_deCheckBox.gridy = 1;
checkBoxPanel.add(getDeCheckBox(), gbc_deCheckBox);
GridBagConstraints gbc_frCheckBox = new GridBagConstraints();
gbc_frCheckBox.anchor = GridBagConstraints.WEST;
gbc_frCheckBox.insets = new Insets(0, 5, 5, 0);
gbc_frCheckBox.gridx = 0;
gbc_frCheckBox.gridy = 2;
checkBoxPanel.add(getFrCheckBox(), gbc_frCheckBox);
GridBagConstraints gbc_esCheckBox = new GridBagConstraints();
gbc_esCheckBox.anchor = GridBagConstraints.WEST;
gbc_esCheckBox.insets = new Insets(0, 5, 5, 0);
gbc_esCheckBox.gridx = 0;
gbc_esCheckBox.gridy = 3;
checkBoxPanel.add(getEsCheckBox(), gbc_esCheckBox);
GridBagConstraints gbc_itCheckBox = new GridBagConstraints();
gbc_itCheckBox.weighty = 1.0;
gbc_itCheckBox.anchor = GridBagConstraints.NORTHWEST;
gbc_itCheckBox.insets = new Insets(0, 5, 0, 0);
gbc_itCheckBox.gridx = 0;
gbc_itCheckBox.gridy = 4;
checkBoxPanel.add(getItCheckBox(), gbc_itCheckBox);
}
return checkBoxPanel;
}
private JCheckBox getEnCheckBox() {
if (enCheckBox == null) {
enCheckBox = new JCheckBox(EN);
private JCheckBox getEnCheckBox()
{
if (enCheckBox == null)
{
enCheckBox = new JCheckBox(EN);
enCheckBox.setSelected(model.getDescription().length() == 0);
}
return enCheckBox;
}
private JCheckBox getDeCheckBox() {
if (deCheckBox == null) {
deCheckBox = new JCheckBox(DE);
private JCheckBox getDeCheckBox()
{
if (deCheckBox == null)
{
deCheckBox = new JCheckBox(DE);
deCheckBox.setSelected(model.getDescriptionDe().length() == 0);
}
return deCheckBox;
}
private JCheckBox getFrCheckBox() {
if (frCheckBox == null) {
frCheckBox = new JCheckBox(FR);
private JCheckBox getFrCheckBox()
{
if (frCheckBox == null)
{
frCheckBox = new JCheckBox(FR);
frCheckBox.setSelected(model.getDescriptionFr().length() == 0);
}
return frCheckBox;
}
private JCheckBox getEsCheckBox() {
if (esCheckBox == null) {
esCheckBox = new JCheckBox(ES);
private JCheckBox getEsCheckBox()
{
if (esCheckBox == null)
{
esCheckBox = new JCheckBox(ES);
esCheckBox.setSelected(model.getDescriptionEs().length() == 0);
}
return esCheckBox;
}
private JCheckBox getItCheckBox() {
if (itCheckBox == null) {
itCheckBox = new JCheckBox(IT);
private JCheckBox getItCheckBox()
{
if (itCheckBox == null)
{
itCheckBox = new JCheckBox(IT);
itCheckBox.setSelected(model.getDescriptionIt().length() == 0);
}
return itCheckBox;
}
private void enableCheckBoxes()
{
String selectedFromLanguage = getFromComboBox().getSelectedItem().toString();
@ -180,14 +207,15 @@ public class TranslationPanel extends JPanel
getEsCheckBox().setEnabled(!getEsCheckBox().getText().equals(selectedFromLanguage));
getItCheckBox().setEnabled(!getItCheckBox().getText().equals(selectedFromLanguage));
}
String getSelectedFromLanguage()
{
String selectedFromLanguage = getFromComboBox().getSelectedItem().toString();
String returnString = selectedFromLanguage.substring(selectedFromLanguage.indexOf("(") +1, selectedFromLanguage.lastIndexOf(")"));
String returnString =
selectedFromLanguage.substring(selectedFromLanguage.indexOf("(") + 1, selectedFromLanguage.lastIndexOf(")"));
return returnString;
}
List<String> getSelectedToLanguages()
{
List<String> returnList = new ArrayList<>();

View File

@ -0,0 +1,97 @@
package se.lantz.gui.translation;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.WindowConstants;
public class TranslationProgressDialog extends JDialog
{
private static final long serialVersionUID = 1L;
private JProgressBar progressBar;
private JLabel textLabel;
public TranslationProgressDialog(Frame frame)
{
super(frame, "Translating", true);
setAlwaysOnTop(true);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setResizable(false);
GridBagLayout gridBagLayout = new GridBagLayout();
getContentPane().setLayout(gridBagLayout);
GridBagConstraints gbc_progressBar = new GridBagConstraints();
gbc_progressBar.weightx = 1.0;
gbc_progressBar.anchor = GridBagConstraints.NORTH;
gbc_progressBar.fill = GridBagConstraints.HORIZONTAL;
gbc_progressBar.insets = new Insets(5, 5, 5, 5);
gbc_progressBar.gridx = 0;
gbc_progressBar.gridy = 0;
getContentPane().add(getProgressBar(), gbc_progressBar);
GridBagConstraints gbc_textLabel = new GridBagConstraints();
gbc_textLabel.insets = new Insets(5, 5, 5, 5);
gbc_textLabel.anchor = GridBagConstraints.NORTH;
gbc_textLabel.weightx = 1.0;
gbc_textLabel.weighty = 1.0;
gbc_textLabel.gridx = 0;
gbc_textLabel.gridy = 1;
getContentPane().add(getTextLabel(), gbc_textLabel);
}
public void updateProgress(String lang)
{
String language = "";
switch (lang)
{
case "en":
language = "English";
break;
case "de":
language = "German";
break;
case "fr":
language = "French";
break;
case "es":
language = "Spanish";
break;
case "it":
language = "Italian";
break;
default:
break;
}
getTextLabel().setText("Translating description to " + language + "...");
this.repaint();
}
public void finish()
{
progressBar.setIndeterminate(false);
getProgressBar().setValue(getProgressBar().getMaximum());
dispose();
}
private JProgressBar getProgressBar()
{
if (progressBar == null)
{
progressBar = new JProgressBar();
progressBar.setIndeterminate(true);
}
return progressBar;
}
private JLabel getTextLabel()
{
if (textLabel == null)
{
textLabel = new JLabel("Translating description to English......");
}
return textLabel;
}
}

View File

@ -0,0 +1,112 @@
package se.lantz.gui.translation;
import java.io.IOException;
import java.util.List;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import se.lantz.model.InfoModel;
import se.lantz.util.DescriptionTranslater;
import se.lantz.util.ExceptionHandler;
public class TranslationWorker extends SwingWorker<Void, String>
{
private TranslationProgressDialog dialog;
private InfoModel model;
private String fromLanguage;
private List<String> toLanguageList;
public TranslationWorker(InfoModel model,
TranslationProgressDialog dialog,
String fromLanguage,
List<String> toLanguageList)
{
this.model = model;
this.dialog = dialog;
this.fromLanguage = fromLanguage;
this.toLanguageList = toLanguageList;
}
@Override
protected Void doInBackground() throws Exception
{
String textToTranslate = "";
switch (fromLanguage)
{
case "en":
textToTranslate = model.getDescription();
break;
case "de":
textToTranslate = model.getDescriptionDe();
break;
case "fr":
textToTranslate = model.getDescriptionFr();
break;
case "es":
textToTranslate = model.getDescriptionEs();
break;
case "it":
textToTranslate = model.getDescriptionIt();
break;
default:
break;
}
if (textToTranslate.isEmpty())
{
//Nothing to translate
return null;
}
for (String toLanguage : toLanguageList)
{
try
{
SwingUtilities.invokeLater(() -> {
dialog.updateProgress(toLanguage);
});
String translatedText = DescriptionTranslater.translate(fromLanguage, toLanguage, textToTranslate);
publish(toLanguage + "¤" + translatedText);
}
catch (IOException e)
{
ExceptionHandler.handleException(e, "Could not translate description");
}
}
return null;
}
@Override
protected void process(List<String> chunks)
{
for (String result : chunks)
{
String[] split = result.split("¤");
switch (split[0])
{
case "en":
model.setDescription(split[1]);
break;
case "de":
model.setDescriptionDe(split[1]);
break;
case "fr":
model.setDescriptionFr(split[1]);
break;
case "es":
model.setDescriptionEs(split[1]);
break;
case "it":
model.setDescriptionIt(split[1]);
break;
default:
break;
}
}
}
@Override
protected void done()
{
dialog.finish();
}
}

View File

@ -2,13 +2,9 @@ package se.lantz.model;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import se.lantz.util.DescriptionTranslater;
import se.lantz.util.ExceptionHandler;
import se.lantz.util.FileManager;
public class InfoModel extends AbstractModel
@ -20,7 +16,7 @@ public class InfoModel extends AbstractModel
private String description_de = "";
private String description_fr = "";
private String description_es = "";
private String description_it = "";
private String description_it = "";
private int year = 0;
private String genre = "";
private String composer = "";
@ -29,14 +25,14 @@ public class InfoModel extends AbstractModel
private String coverFile = "";
private String screens1File = "";
private String screens2File = "";
//These images have there original sizes. Scale cover to 122x175 once storing it
private BufferedImage coverImage;
private BufferedImage screen1Image;
private BufferedImage screen2Image;
private Path gamesPath;
private String oldGamesFile = "";
private String oldCoverFile = "";
private String oldScreens1File = "";
@ -46,13 +42,13 @@ public class InfoModel extends AbstractModel
{
return title;
}
public void setTitleFromDb(String title)
{
titleInDb = title;
this.title = title;
}
public String getTitleInDb()
{
return titleInDb;
@ -63,7 +59,7 @@ public class InfoModel extends AbstractModel
String old = getTitle();
this.title = title;
if (!Objects.equals(old, title))
{
{
notifyChange();
}
}
@ -84,7 +80,7 @@ public class InfoModel extends AbstractModel
notifyChange();
}
}
public String getDescriptionDe()
{
return description_de;
@ -101,7 +97,7 @@ public class InfoModel extends AbstractModel
notifyChange();
}
}
public String getDescriptionFr()
{
return description_fr;
@ -118,7 +114,7 @@ public class InfoModel extends AbstractModel
notifyChange();
}
}
public String getDescriptionEs()
{
return description_es;
@ -135,7 +131,7 @@ public class InfoModel extends AbstractModel
notifyChange();
}
}
public String getDescriptionIt()
{
return description_it;
@ -318,12 +314,12 @@ public class InfoModel extends AbstractModel
notifyChange();
}
}
public Path getGamesPath()
{
return gamesPath;
}
public void setGamesPath(File file)
{
Path old = getGamesPath();
@ -333,18 +329,18 @@ public class InfoModel extends AbstractModel
String fileEnding = file.getName().substring(file.getName().indexOf("."));
if (fileEnding.endsWith(".gz") || fileEnding.endsWith(".GZ"))
{
setGamesFile(fileName + fileEnding);
setGamesFile(fileName + fileEnding);
}
else
{
setGamesFile(fileName + fileEnding +".gz");
setGamesFile(fileName + fileEnding + ".gz");
}
if (!Objects.equals(old, gamesPath))
{
notifyChange();
}
}
public boolean updateFileNames()
{
if (isNewGame() || isTitleChanged() || screenNamesNeedsUpdate())
@ -354,7 +350,7 @@ public class InfoModel extends AbstractModel
oldScreens1File = getScreens1File();
oldScreens2File = getScreens2File();
oldGamesFile = getGamesFile();
disableChangeNotification(true);
String fileName = FileManager.generateFileNameFromTitle(this.title);
if (!getCoverFile().isEmpty() || getCoverImage() != null)
@ -379,17 +375,17 @@ public class InfoModel extends AbstractModel
}
return false;
}
public boolean isNewGame()
{
return titleInDb.isEmpty();
}
public boolean isTitleChanged()
{
return !titleInDb.isEmpty() && !titleInDb.equalsIgnoreCase(title);
}
public boolean screenNamesNeedsUpdate()
{
if (getScreens1File().isEmpty() && getScreen1Image() != null)
@ -401,15 +397,15 @@ public class InfoModel extends AbstractModel
return true;
}
//Must have names ending with -00.png and -01.png
return (!getScreens1File().isEmpty() && !getScreens1File().endsWith("-00.png")) || ((!getScreens2File().isEmpty() && !getScreens2File().endsWith("-01.png")));
return (!getScreens1File().isEmpty() && !getScreens1File().endsWith("-00.png")) ||
((!getScreens2File().isEmpty() && !getScreens2File().endsWith("-01.png")));
}
public boolean isAnyScreenRenamed()
{
return !oldScreens1File.isEmpty() || !oldScreens2File.isEmpty();
}
public void resetImagesAndOldFileNames()
{
this.coverImage = null;
@ -441,63 +437,4 @@ public class InfoModel extends AbstractModel
{
return oldScreens2File;
}
public void translateDescription(String from, List<String> toList)
{
this.disableChangeNotification(true);
String textToTranslate = "";
switch (from)
{
case "en":
textToTranslate = getDescription();
break;
case "de":
textToTranslate = getDescriptionDe();
break;
case "fr":
textToTranslate = getDescriptionFr();
break;
case "es":
textToTranslate = getDescriptionEs();
break;
case "it":
textToTranslate = getDescriptionIt();
break;
default:
break;
}
for (String to : toList)
{
try
{
String translatedText = DescriptionTranslater.translate(from, to, textToTranslate);
switch (to)
{
case "en":
setDescription(translatedText);
break;
case "de":
setDescriptionDe(translatedText);
break;
case "fr":
setDescriptionFr(translatedText);
break;
case "es":
setDescriptionEs(translatedText);
break;
case "it":
setDescriptionIt(translatedText);
break;
default:
break;
}
}
catch (IOException e)
{
ExceptionHandler.handleException(e, "Could not translate description");
}
}
this.disableChangeNotification(false);
this.notifyChange();
}
}