diff --git a/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java b/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java
index 403fc525..880b06f4 100644
--- a/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java
+++ b/diylc/diylc-core/src/org/diylc/common/IPlugInPort.java
@@ -90,7 +90,9 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
public static final String SNAP_TO_NONE = "None";
public static final String SNAP_TO_GRID = "Grid";
public static final String SNAP_TO_COMPONENTS = "Components";
- public static final String SNAP_TO_DEFAULT = SNAP_TO_GRID;
+ public static final String SNAP_TO_DEFAULT = SNAP_TO_GRID;
+
+ public static final String LANGUAGE = "language";
public static final int DND_TOGGLE_STICKY = 0x1;
public static final int DND_TOGGLE_SNAP = 0x40000000;
@@ -101,7 +103,7 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
public static final int NOBUTTON = 0;
public static final int BUTTON1 = 1;
public static final int BUTTON2 = 2;
- public static final int BUTTON3 = 3;
+ public static final int BUTTON3 = 3;
/**
* Returns size of the canvas that takes project dimensions into account as well as zoom level.
diff --git a/diylc/diylc-core/src/org/diylc/lang/TranslateUtil.java b/diylc/diylc-core/src/org/diylc/lang/TranslateUtil.java
new file mode 100644
index 00000000..f10795c7
--- /dev/null
+++ b/diylc/diylc-core/src/org/diylc/lang/TranslateUtil.java
@@ -0,0 +1,137 @@
+/*
+ *
+ * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
+ *
+ * This file is part of DIYLC.
+ *
+ * DIYLC 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.
+ *
+ * DIYLC 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 DIYLC. If not, see
+ * .
+ */
+package org.diylc.lang;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.log4j.Logger;
+import org.diylc.appframework.miscutils.ConfigurationManager;
+import org.diylc.common.IPlugInPort;
+
+public class TranslateUtil {
+
+ private static final String LANG_DIR = "lang";
+
+ private static final Logger LOG = Logger.getLogger(TranslateUtil.class);
+
+ private static Map dict = null;
+ private static List missing;
+
+ public static String translate(String text) {
+ if (text == null || text.length() <= 1)
+ return text;
+
+ try {
+ // don't translate numbers
+ Double.parseDouble(text);
+ return text;
+ } catch (Exception e) {
+ }
+
+ if (dict != null) {
+ if (dict.containsKey(text.toLowerCase())) {
+ return dict.get(text.toLowerCase());
+ } else {
+ if ("true".equalsIgnoreCase(System.getProperty("org.diylc.storeDict"))) {
+ List missing = getMissing();
+ if (!missing.contains(text)) {
+ missing.add(text);
+ Collections.sort(missing);
+ try (PrintWriter out = new PrintWriter("dict.txt")) {
+ for (String m : missing) {
+ out.println(m);
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ return text;
+ }
+
+ public static void configure() {
+ String language = ConfigurationManager.getInstance().readString(IPlugInPort.LANGUAGE, "English");
+ if (language != null)
+ load(language);
+ }
+
+ private static void load(String language) {
+ LOG.info("Loading translation for " + language);
+ dict = new HashMap();
+ try {
+ try (Stream stream = Files.lines(
+ Paths.get(LANG_DIR + File.separator + language + ".txt"), StandardCharsets.UTF_8)) {
+ stream.forEach(s -> {
+ if (s.contains("|")) {
+ String[] parts = s.split("\\|");
+ if (parts.length == 2)
+ dict.put(parts[0].toLowerCase().trim(), parts[1].trim());
+ } else {
+ dict.put(s.toLowerCase(), s);
+ }
+ });
+ } catch (IOException e) {
+ LOG.error("Error loading language file", e);
+ }
+ } catch (Exception e) {
+ LOG.error("Error loading language file", e);
+ }
+ }
+
+ private static List getMissing() {
+ if (missing == null) {
+ missing = new ArrayList();
+ try {
+ try (Stream stream = Files.lines(Paths.get("dict.txt"), StandardCharsets.UTF_8)) {
+ stream.forEach(s -> missing.add(s));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } catch (Exception e) {
+
+ }
+ }
+ return missing;
+ }
+
+ public static List getAvailableLanguages() {
+ try (Stream walk = Files.walk(Paths.get(LANG_DIR))) {
+
+ return walk.filter(Files::isRegularFile).map(x -> x.toString()).collect(Collectors.toList());
+ } catch (IOException e) {
+ LOG.error("Error fetching available languages");
+ return null;
+ }
+ }
+}
diff --git a/diylc/diylc-core/src/org/diylc/presenter/ComponentProcessor.java b/diylc/diylc-core/src/org/diylc/presenter/ComponentProcessor.java
index 4a269309..4ef1a41a 100644
--- a/diylc/diylc-core/src/org/diylc/presenter/ComponentProcessor.java
+++ b/diylc/diylc-core/src/org/diylc/presenter/ComponentProcessor.java
@@ -46,7 +46,8 @@ import org.diylc.core.IPropertyValidator;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
-import org.diylc.core.annotations.KeywordPolicy;
+import org.diylc.core.annotations.KeywordPolicy;
+import org.diylc.lang.TranslateUtil;
/**
* Utility class with component processing methods.
@@ -173,7 +174,15 @@ public class ComponentProcessor {
setterName = setter.getName();
} catch (NoSuchMethodException e) {
LOG.debug("No matching setter found for \"" + getter.getName() + "\". Skipping...");
- }
+ }
+
+ TranslateUtil.translate(name); // temporary, just to make sure we catch it in the dict
+ if (getter.getReturnType().isEnum()) {
+ for(Object o : getter.getReturnType().getEnumConstants()) {
+ TranslateUtil.translate(o.toString());
+ }
+ }
+
PropertyWrapper property =
new PropertyWrapper(name, getter.getReturnType(), getter.getName(), setterName,
annotation.defaultable(), validator, annotation.sortOrder());
diff --git a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java
index f0a13e59..c9fc5740 100644
--- a/diylc/diylc-core/src/org/diylc/presenter/Presenter.java
+++ b/diylc/diylc-core/src/org/diylc/presenter/Presenter.java
@@ -81,6 +81,7 @@ import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.IAutoCreator;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
+import org.diylc.lang.TranslateUtil;
import org.diylc.netlist.Group;
import org.diylc.netlist.Netlist;
import org.diylc.netlist.NetlistAnalyzer;
@@ -102,6 +103,32 @@ import com.thoughtworks.xstream.io.xml.DomDriver;
*/
public class Presenter implements IPlugInPort {
+ private static final String REACHED_BOTTOM =
+ TranslateUtil.translate("Selected component(s) have reached the bottom of their layer. Do you want to force the selection to the back?");
+ private static final String SEND_SELECTION_TO_BACK = TranslateUtil.translate("Send Selection to Back");
+ private static final String SAVE_AS_VARIANT = TranslateUtil.translate("Save as Variant");
+ private static final String VARIANT_EXISTS = TranslateUtil.translate("A variant with that name already exists. Overwrite?");
+ private static final String ROTATE_CHANGE =
+ TranslateUtil.translate("Selection contains components that cannot be rotated. Do you want to exclude them?");
+ private static final String MIRRORING_CHANGE =
+ TranslateUtil.translate("Mirroring operation will change the circuit. Do you want to continue?");
+ private static final String MIRROR_SELECTION = TranslateUtil.translate("Mirror Selection");
+ private static final String ROTATE_SELECTION = TranslateUtil.translate("Rotate Selection");
+ private static final String CANNOT_MIRROR =
+ TranslateUtil.translate("Selection contains components that cannot be mirrored. Do you want to exclude them?");
+ private static final String BRING_SELECTION_TO_FRONT = TranslateUtil.translate("Bring Selection to Front");
+ private static final String REACHED_TOP =
+ TranslateUtil.translate("Selected component(s) have reached the top of their layer. Do you want to force the selection to the top?");
+ private static final String WARNING = TranslateUtil.translate("Warning");
+ private static final String UNSAVED_CHANGES = TranslateUtil.translate("There are unsaved changes. Would you like to save them?");
+ private static final String ERROR_SLOT = TranslateUtil.translate("Could not set component type slot. Check log for details.");
+ private static final String ERROR_SAVE = TranslateUtil.translate("Could not save the project to file. Check the log for details.");
+ private static final String ERROR_CREATE = TranslateUtil.translate("Could not create component. Check log for details.");
+ private static final String ERROR_EDIT = TranslateUtil.translate("Error occured while editing selection. Check the log for details.");
+ private static final String ERROR_NEW = TranslateUtil.translate("Could not create a new file. Check the log for details.");
+ private static final String ERROR = TranslateUtil.translate("Error");
+ private static final String APPLY_ERROR = "Could not apply changes. Check the log for details.";
+
private static final Logger LOG = Logger.getLogger(Presenter.class);
public static VersionNumber CURRENT_VERSION = new VersionNumber(4, 0, 0);
@@ -137,7 +164,7 @@ public class Presenter implements IPlugInPort {
public static final int ICON_SIZE = 32;
- private static final int MAX_RECENT_FILES = 20;
+ private static final int MAX_RECENT_FILES = 20;
private Project currentProject;
private Map> componentTypes;
@@ -294,7 +321,7 @@ public class Presenter implements IPlugInPort {
DrawingCache.Instance.clear();
} catch (Exception e) {
LOG.error("Could not create new file", e);
- view.showMessage("Could not create a new file. Check the log for details.", "Error", IView.ERROR_MESSAGE);
+ view.showMessage(ERROR_NEW, ERROR, IView.ERROR_MESSAGE);
}
}
@@ -314,7 +341,7 @@ public class Presenter implements IPlugInPort {
builder.append("
");
}
builder.append("