diff --git a/src/com/gpl/rpg/atcontentstudio/model/WorkspaceSettings.java b/src/com/gpl/rpg/atcontentstudio/model/WorkspaceSettings.java index 79ce879..3072542 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/WorkspaceSettings.java +++ b/src/com/gpl/rpg/atcontentstudio/model/WorkspaceSettings.java @@ -38,7 +38,7 @@ public class WorkspaceSettings { public static String DEFAULT_IMG_EDITOR_COMMAND = "gimp"; public Setting imageEditorCommand = new PrimitiveSetting("imageEditorCommand", DEFAULT_IMG_EDITOR_COMMAND); - public static String[] LANGUAGE_LIST = new String[]{null, "de", "ru", "pl", "fr", "it", "es", "nl", "uk", "ca", "sv", "pt", "pt_BR", "zh_Hant", "zh_Hans", "ja", "cs", "tr", "ko", "hu", "sl", "bg", "id", "fi", "th", "gl", "ms" ,"pa", "az"}; + public static String[] LANGUAGE_LIST = new String[]{null, "de", "ru", "pl", "fr", "it", "es", "nl", "uk", "ca", "sv", "pt", "pt_BR", "zh_Hant", "zh_Hans", "ja", "cs", "tr", "ko", "hu", "sl", "bg", "id", "fi", "th", "gl", "ms" ,"pa", "az", "nb"}; public Setting translatorLanguage = new NullDefaultPrimitiveSetting("translatorLanguage"); public static Boolean DEFAULT_ALLOW_INTERNET = true; public Setting useInternet = new PrimitiveSetting("useInternet", DEFAULT_ALLOW_INTERNET); diff --git a/src/com/gpl/rpg/atcontentstudio/ui/AboutEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/AboutEditor.java index 4401e45..fef267c 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/AboutEditor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/AboutEditor.java @@ -132,6 +132,7 @@ public class AboutEditor extends Editor { editorTabsHolder.add("BeanShell License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.LGPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); editorTabsHolder.add("SipHash for Java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.siphash-zackehh.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); editorTabsHolder.add("jsoup License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.jsoup.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); + editorTabsHolder.add("General PO Parser License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); editorTabsHolder.add("ATCS License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text")); } diff --git a/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PoPotWriter.java b/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PoPotWriter.java new file mode 100644 index 0000000..507f0a4 --- /dev/null +++ b/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PoPotWriter.java @@ -0,0 +1,86 @@ +package com.gpl.rpg.atcontentstudio.ui.tools.i18n; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class PoPotWriter { + + Map> stringsResources = new LinkedHashMap>(); + Map translations = new LinkedHashMap(); + File f; + + public static void writePoFile(Map> stringsResources, Map translations, File destination) { + try { + FileWriter fw = new FileWriter(destination); + if (translations.get("") != null) { + fw.write(translations.get("")); + writeEndOfEntry(fw); + } + if (translations.get("translator-credits") != null) { + List refs = new LinkedList(); + refs.add("[none]"); + writeReferences(fw, refs); + writeMsgId(fw, "translator-credits"); + writeMsgStr(fw, translations.get("translator-credits")); + writeEndOfEntry(fw); + } + for (String msg : stringsResources.keySet()) { + writeReferences(fw, stringsResources.get(msg)); + writeMsgId(fw, msg); + writeMsgStr(fw, translations.get(msg)); + writeEndOfEntry(fw); + } + fw.flush(); + fw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void writePotFile(Map> stringsResources, File destination) { + try { + FileWriter fw = new FileWriter(destination); + for (String msg : stringsResources.keySet()) { + writeReferences(fw, stringsResources.get(msg)); + writeMsgId(fw, msg); + writeMsgStr(fw, ""); + writeEndOfEntry(fw); + } + fw.flush(); + fw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void writeReferences(Writer w, List references) throws IOException { + for (String ref : references) { + w.write("#: "); + w.write(ref); + w.write("\n"); + } + } + + private static void writeMsgId(Writer w, String msg) throws IOException { + w.write("msgid \""); + w.write(msg); + w.write("\"\n"); + } + + private static void writeMsgStr(Writer w, String translation) throws IOException { + w.write("msgstr \""); + w.write(translation == null ? "" : translation); + w.write("\"\n"); + } + + private static void writeEndOfEntry(Writer w) throws IOException { + w.write("\n"); + } + +} diff --git a/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotComparator.java b/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotComparator.java index f326769..3702545 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotComparator.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotComparator.java @@ -1,18 +1,42 @@ package com.gpl.rpg.atcontentstudio.ui.tools.i18n; import java.io.File; +import java.io.FileFilter; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Vector; +import javax.swing.JOptionPane; + import com.gpl.rpg.atcontentstudio.model.Project; import net.launchpad.tobal.poparser.POEntry; import net.launchpad.tobal.poparser.POFile; import net.launchpad.tobal.poparser.POParser; + +/** + * + * @author Kevin + * + * To use this, paste the following script in the beanshell console of ATCS. + * Don't forget to change the project number to suit your needs. + * + * import com.gpl.rpg.atcontentstudio.model.Workspace; + * import com.gpl.rpg.atcontentstudio.ui.tools.i18n.PotGenerator; + * import com.gpl.rpg.atcontentstudio.ui.tools.i18n.PotComparator; + * + * proj = Workspace.activeWorkspace.projects.get(7); + * PotGenerator.generatePotFileForProject(proj); + * comp = new PotComparator(proj); + * comp.compare(); + * comp.updatePoFiles(proj); + * + * + * + */ public class PotComparator { Map> stringsResourcesNew = new LinkedHashMap>(); @@ -20,6 +44,10 @@ public class PotComparator { Map> stringsResourcesOld = new LinkedHashMap>(); Map resourcesStringsOld = new LinkedHashMap(); + + Map msgIdToReplace = new LinkedHashMap(); + List msgIdToReview = new LinkedList(); + List msgIdOutdated = new LinkedList(); public PotComparator(Project proj) { @@ -47,10 +75,13 @@ public class PotComparator { String msgid = msgids.get(0); if (msgids.size() > 1) { for (int i = 1; i < msgids.size(); i++) { - msgid += "\n"; msgid += msgids.get(i); } } + if (msgid.contains("\\n")) { + msgid = msgid.replaceAll("\\\\n", "\\\\n\"\n\""); + msgid = "\"\n\""+msgid; + } for (String resLine : resources) { String[] resArray = resLine.split(" "); for (String res : resArray) { @@ -72,27 +103,29 @@ public class PotComparator { if (!newString.equals(oldString)) { List allOldResources = stringsResourcesOld.get(oldString); List allNewResources = stringsResourcesNew.get(oldString); - System.out.println("---------------------------------------------"); - System.out.println("--- TYPO CHECK ------------------------------"); - System.out.println("---------------------------------------------"); - System.out.println("String at: "+oldRes); + StringBuffer sb = new StringBuffer(); + sb.append("---------------------------------------------\n"); + sb.append("--- TYPO CHECK ------------------------------\n"); + sb.append("---------------------------------------------\n"); + sb.append("String at: "+oldRes+"\n"); if (allOldResources.size() > 1) { - System.out.println("Also present at:"); + sb.append("Also present at:\n"); for (String res : allOldResources) { if (!res.equals(oldRes)) { - System.out.println("- "+res); + sb.append("- "+res+"\n"); } } } if (allNewResources != null) { - System.out.println("Still present at: "); + sb.append("Still present at: \n"); for (String res : allNewResources) { - System.out.println("- "+res); + sb.append("- "+res+"\n"); } } - System.out.println("Was : \""+oldString+"\""); - System.out.println("Now : \""+newString+"\""); - + sb.append("Was : \""+oldString+"\"\n"); + sb.append("Now : \""+newString+"\"\n"); + System.out.println(sb.toString()); + showTypoDialog(oldString, newString, sb.toString()); } } else { List allOldResources = stringsResourcesOld.get(oldString); @@ -151,4 +184,127 @@ public class PotComparator { } } + private void showTypoDialog(String oldMsg, String newMsg, String checkReport) { + String typo = "Typo"; + String review = "Review"; + String outdated = "Outdated"; + String none = "None"; + Object[] options = new Object[] {typo, review, outdated, none}; + + int result = JOptionPane.showOptionDialog(null, checkReport, "Choose action", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, typo); + + if (result < 0 || result >= options.length) { + System.out.println("No decision"); + return; + } + + System.out.println("Decision: "+options[result]); + + if (options[result] != none) { + msgIdToReplace.put(oldMsg, newMsg); + if (options[result] == review) { + msgIdToReview.add(newMsg); + } else if (options[result] == outdated) { + msgIdOutdated.add(newMsg); + } + } + + } + + + public void updatePoFiles(Project proj) { + File poFolder = new File(proj.baseContent.baseFolder.getAbsolutePath()+File.separator+"assets"+File.separator+"translation"); + File[] poFiles = poFolder.listFiles(new FileFilter() { + @Override + public boolean accept(File arg0) { + return arg0.isFile() && arg0.getName().endsWith(".po"); + } + }); + + for (File f : poFiles) { + updatePoFile(proj, f); + } + } + + private void updatePoFile(Project proj, File f) { + POParser parser = new POParser(); + POFile poFile = parser.parseFile(f); + + Map translations = new LinkedHashMap(); + + //Collect existing translations + if (poFile.getHeader() != null) { + Vector msgstrs = poFile.getHeader().getStringsByType(POEntry.StringType.HEADER); + String header = ""; + if (!msgstrs.isEmpty()) { + if (msgstrs.size() == 1) { + header = msgstrs.get(0); + } else { + for (String msgstr : msgstrs) { + header += msgstr; + header += "\n"; + } + } + } + translations.put("", header); + } + + for (POEntry entry : poFile.getEntryArray()) { + Vector msgids = entry.getStringsByType(POEntry.StringType.MSGID); + Vector msgstrs = entry.getStringsByType(POEntry.StringType.MSGSTR); + if (msgids == null || msgids.size() == 0) continue; + String msgid = msgids.get(0); + if (msgids.size() > 1) { + for (int i = 1; i < msgids.size(); i++) { + msgid += msgids.get(i); + } + } + if (msgid.contains("\\n")) { + msgid = msgid.replaceAll("\\\\n", "\\\\n\"\n\""); + msgid = "\"\n\""+msgid; + } + String translation = ""; + if (!msgstrs.isEmpty()) { + if (msgstrs.size() == 1) { + translation = msgstrs.get(0); + } else { + for (String msgstr : msgstrs) { + translation += msgstr; + } + } + if (translation.contains("\\n")) { + translation = translation.replaceAll("\\\\n", "\\\\n\"\n\""); + translation = "\"\n\""+translation; + } + } + translations.put(msgid, translation); + } + + //Patch data + for (String oldId : msgIdToReplace.keySet()) { + String newId = msgIdToReplace.get(oldId); + if (translations.containsKey(oldId)) { + String trans = translations.get(oldId); + translations.remove(oldId); + translations.put(newId, trans); + } + } + + for (String msgid : msgIdToReview) { + if (translations.containsKey(msgid)) { + String trans = translations.get(msgid); + if (trans != null && trans.length() >= 1) translations.put(msgid, "[REVIEW]"+trans); + } + } + + for (String msgid : msgIdOutdated) { + if (translations.containsKey(msgid)) { + String trans = translations.get(msgid); + if (trans != null && trans.length() >= 1) translations.put(msgid, "[OUTDATED]"+trans); + } + } + + PoPotWriter.writePoFile(stringsResourcesNew, translations, new File(proj.alteredContent.baseFolder.getAbsolutePath()+File.separator+f.getName())); + } + } diff --git a/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotGenerator.java b/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotGenerator.java index 14b5db6..10cbbeb 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotGenerator.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotGenerator.java @@ -1,8 +1,6 @@ package com.gpl.rpg.atcontentstudio.ui.tools.i18n; import java.io.File; -import java.io.FileWriter; -import java.io.IOException; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -69,30 +67,13 @@ public class PotGenerator { } File f = new File(proj.alteredContent.baseFolder, "english.pot"); - try { - FileWriter fw = new FileWriter(f); - for (String msg : stringsResources.keySet()) { - for (String ctx : stringsResources.get(msg)) { - fw.write("#: "); - fw.write(ctx); - fw.write("\n"); - } - fw.write("msgid \""); - fw.write(msg); - fw.write("\"\nmsgstr \"\"\n\n"); - - } - fw.flush(); - fw.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + PoPotWriter.writePotFile(stringsResources, f); } private static void pushString (Map> stringsResources, Map resourcesStrings, String translatableString, String resourceIdentifier) { if (translatableString == null) return; + if (translatableString.length() == 0) return; if (translatableString.contains("\n")) { translatableString = translatableString.replaceAll("\n", "\\\\n\"\n\""); translatableString = "\"\n\""+translatableString; diff --git a/src/net/launchpad/tobal/poparser/POFile.java b/src/net/launchpad/tobal/poparser/POFile.java index d55a4d1..919db09 100644 --- a/src/net/launchpad/tobal/poparser/POFile.java +++ b/src/net/launchpad/tobal/poparser/POFile.java @@ -58,6 +58,10 @@ public class POFile { return entries.length; } + + public POEntry getHeader() { + return header; + } /** * Checks if the specified flag is set in the entry, diff --git a/src/net/launchpad/tobal/poparser/POParser.java b/src/net/launchpad/tobal/poparser/POParser.java index b516231..ec315f1 100644 --- a/src/net/launchpad/tobal/poparser/POParser.java +++ b/src/net/launchpad/tobal/poparser/POParser.java @@ -8,11 +8,10 @@ */ package net.launchpad.tobal.poparser; +import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.io.Reader; -import java.io.BufferedReader; import java.util.Vector; public class POParser