Fix 2 TODO items:
authorNiki Roo <niki@nikiroo.be>
Sun, 8 May 2016 08:54:28 +0000 (10:54 +0200)
committerNiki Roo <niki@nikiroo.be>
Sun, 8 May 2016 08:54:28 +0000 (10:54 +0200)
- 'R' action not visible in EN language
- "--save-config" not saving all languages

README.md
src/be/nikiroo/jvcard/launcher/Main.java
src/be/nikiroo/jvcard/resources/Bundles.java
src/be/nikiroo/jvcard/resources/FixedResourceBundleControl.java
src/be/nikiroo/jvcard/resources/ResourceList.java [new file with mode: 0644]
src/be/nikiroo/jvcard/resources/bundles/TransBundle.java
src/be/nikiroo/jvcard/resources/resources_en.properties

index c0e210c703b6874f9620cbd14096e8bf35d974ac..f9805cb26b7b80a68fb9e3cfc33a08b9f9b6387c 100644 (file)
--- a/README.md
+++ b/README.md
@@ -15,17 +15,19 @@ Small TUI (text mode) VCard manager (also supports abook files)
 
 ## TODO
 
-- lot of other things
-- correct UI for new contact/new data/edit data-types
-- update the screenshots
-- support escape as cancel in new X, new Y..
-- allow adding a new addressbook (and ask where to save it, offer current dir OR last input dir as default)
-- make sure it works OK for "jvcard.jar /dir/to/directory-full-of-vcf-files"
-- → maybe a mode with 1 contact/file ? and take the name from the contact to show in the list of "files" ?
-- → add action "open as addressbook" ?
-- find out why "R" is not displayed as a possible action (edit RAW) when viewing a contact)
-- add: modal dialogue -> "sub menu" (change the action keys) ? (maybe a "second action mode" and a copy of the MainContent)
-- change --save-dir so that it saves ALL the translation files (open + scan dir?)
+- [ ] lot of other things
+- [ ] correct UI for new contact/new data/edit data-types
+- [ ] update the screenshots
+- [ ] support escape as cancel in new X, new Y..
+- [ ] allow adding a new addressbook (and ask where to save it, offer current dir OR last input dir as default)
+-      make sure it works OK for "jvcard.jar /dir/to/directory-full-of-vcf-files"
+-      maybe a mode with 1 contact/file ?
+-      and take the name from the contact to show in the list of "files" ?
+-      add action "open as addressbook" ?
+- [x] find out why "R" is not displayed as a possible action (edit RAW) when viewing a contact)
+-      it was missing in resources-en
+- [ ] add: modal dialogue -> "sub menu" (change the action keys) ? (maybe a "second action mode" and a copy of the MainContent)
+- [x] change --save-dir so that it saves ALL the translation files (open + scan dir?)
 
 ## Screenshots
 
index 7feaaa4cee28563aa0cdb945e6f99bd1e39d7b03..54238c8b86bf08e1fd872969e56d4f7aee6677ce 100644 (file)
@@ -272,8 +272,11 @@ public class Main {
                                        }
                                }
 
-                               transService.updateFile(dir); // current lang TransBundle
-                               new TransBundle().updateFile(dir);
+                               new TransBundle().updateFile(dir); // default locale
+                               for (String lang : TransBundle.getKnownLanguages()) {
+                                       new TransBundle(lang).updateFile(dir);
+                               }
+
                                new ColorBundle().updateFile(dir);
                                new DisplayBundle().updateFile(dir);
                                new RemoteBundle().updateFile(dir);
index ef6e0d750ec2e9b80f518d3f756eab04787e114c..04b6f707d1dcaeb1935d036d7fcd2f3cf5ff6597 100644 (file)
@@ -17,6 +17,10 @@ import java.util.ResourceBundle;
  *
  */
 public class Bundles {
+       /**
+        * The configuration directory where we try to get the <tt>.properties</tt>
+        * in priority, or NULL to get the information from the compiled resources.
+        */
        static private String confDir = getConfDir();
 
        /**
@@ -69,6 +73,16 @@ public class Bundles {
                Bundles.confDir = confDir;
        }
 
+       /**
+        * Get the primary configuration directory to look for <tt>.properties</tt>
+        * files in.
+        * 
+        * @return the directory
+        */
+       static public String getDirectory() {
+               return Bundles.confDir;
+       }
+
        /**
         * This class encapsulate a {@link ResourceBundle} in UTF-8. It only allows
         * to retrieve values associated to an enumeration, and allows some
index ca3114e4ccf6014ab7a6e7d83e3f304839a8a4f6..25832a2f7a9c3092ef805eb928d95bc0ae6d2fa2 100644 (file)
@@ -35,6 +35,7 @@ class FixedResourceBundleControl extends Control {
                this.outsideWorld = outsideWorld;
        }
 
+       @Override
        public ResourceBundle newBundle(String baseName, Locale locale,
                        String format, ClassLoader loader, boolean reload)
                        throws IllegalAccessException, InstantiationException, IOException {
@@ -56,9 +57,8 @@ class FixedResourceBundleControl extends Control {
                } else {
                        // New code to support outside resources:
                        if (outsideWorld != null) {
-                               String pkg = this.getClass().getPackage().getName()
-                                               .replaceAll("\\.", File.separator)
-                                               + File.separator;
+                               String pkg = this.getClass().getPackage().getName();
+                               pkg = pkg.replaceAll("\\.", File.separator) + File.separator;
 
                                if (resourceName.startsWith(pkg)) {
                                        try {
diff --git a/src/be/nikiroo/jvcard/resources/ResourceList.java b/src/be/nikiroo/jvcard/resources/ResourceList.java
new file mode 100644 (file)
index 0000000..6f87c93
--- /dev/null
@@ -0,0 +1,123 @@
+package be.nikiroo.jvcard.resources;
+
+// code copied from from:
+//             http://forums.devx.com/showthread.php?t=153784,
+// via:
+//             http://stackoverflow.com/questions/3923129/get-a-list-of-resources-from-classpath-directory
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+/**
+ * list resources available from the classpath @ *
+ */
+public class ResourceList {
+
+       /**
+        * for all elements of java.class.path get a Collection of resources Pattern
+        * pattern = Pattern.compile(".*"); gets all resources
+        * 
+        * @param pattern
+        *            the pattern to match
+        * @return the resources in the order they are found
+        */
+       public static Collection<String> getResources(final Pattern pattern) {
+               final ArrayList<String> retval = new ArrayList<String>();
+               final String classPath = System.getProperty("java.class.path", ".");
+               final String[] classPathElements = classPath.split(System
+                               .getProperty("path.separator"));
+               for (final String element : classPathElements) {
+                       retval.addAll(getResources(element, pattern));
+               }
+               return retval;
+       }
+
+       private static Collection<String> getResources(final String element,
+                       final Pattern pattern) {
+               final ArrayList<String> retval = new ArrayList<String>();
+               final File file = new File(element);
+               if (file.isDirectory()) {
+                       retval.addAll(getResourcesFromDirectory(file, pattern));
+               } else {
+                       retval.addAll(getResourcesFromJarFile(file, pattern));
+               }
+               return retval;
+       }
+
+       private static Collection<String> getResourcesFromJarFile(final File file,
+                       final Pattern pattern) {
+               final ArrayList<String> retval = new ArrayList<String>();
+               ZipFile zf;
+               try {
+                       zf = new ZipFile(file);
+               } catch (final ZipException e) {
+                       throw new Error(e);
+               } catch (final IOException e) {
+                       throw new Error(e);
+               }
+               final Enumeration<? extends ZipEntry> e = zf.entries();
+               while (e.hasMoreElements()) {
+                       final ZipEntry ze = (ZipEntry) e.nextElement();
+                       final String fileName = ze.getName();
+                       final boolean accept = pattern.matcher(fileName).matches();
+                       if (accept) {
+                               retval.add(fileName);
+                       }
+               }
+               try {
+                       zf.close();
+               } catch (final IOException e1) {
+                       throw new Error(e1);
+               }
+               return retval;
+       }
+
+       private static Collection<String> getResourcesFromDirectory(
+                       final File directory, final Pattern pattern) {
+               final ArrayList<String> retval = new ArrayList<String>();
+               final File[] fileList = directory.listFiles();
+               for (final File file : fileList) {
+                       if (file.isDirectory()) {
+                               retval.addAll(getResourcesFromDirectory(file, pattern));
+                       } else {
+                               try {
+                                       final String fileName = file.getCanonicalPath();
+                                       final boolean accept = pattern.matcher(fileName).matches();
+                                       if (accept) {
+                                               retval.add(fileName);
+                                       }
+                               } catch (final IOException e) {
+                                       throw new Error(e);
+                               }
+                       }
+               }
+               return retval;
+       }
+
+       /**
+        * list the resources that match args[0]
+        * 
+        * @param args
+        *            args[0] is the pattern to match, or list all resources if
+        *            there are no args
+        */
+       public static void main(final String[] args) {
+               Pattern pattern;
+               if (args.length < 1) {
+                       pattern = Pattern.compile(".*");
+               } else {
+                       pattern = Pattern.compile(args[0]);
+               }
+               final Collection<String> list = ResourceList.getResources(pattern);
+               for (final String name : list) {
+                       System.out.println(name);
+               }
+       }
+}
index 7199158bba8d227322e4cc00e4d3bc52af0dbcf2..5acd704402887bcb2e570b8f3c810c756db6e23e 100644 (file)
@@ -3,11 +3,15 @@ package be.nikiroo.jvcard.resources.bundles;
 import java.io.File;
 import java.io.IOException;
 import java.io.Writer;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Locale;
+import java.util.regex.Pattern;
 
 import be.nikiroo.jvcard.resources.Bundles;
 import be.nikiroo.jvcard.resources.Bundles.Bundle;
 import be.nikiroo.jvcard.resources.Bundles.Target;
+import be.nikiroo.jvcard.resources.ResourceList;
 import be.nikiroo.jvcard.resources.enums.StringId;
 
 /**
@@ -20,6 +24,7 @@ import be.nikiroo.jvcard.resources.enums.StringId;
 public class TransBundle extends Bundle<StringId> {
        private boolean utf = true;
        private Locale locale;
+       private boolean defaultLocale = false;
 
        /**
         * Create a translation service with the default language.
@@ -108,6 +113,7 @@ public class TransBundle extends Bundle<StringId> {
         *            instance
         */
        private void setLanguage(String language) {
+               defaultLocale = (language == null || language.length() == 0);
                locale = getLocaleFor(language);
                map = getBundle(Target.resources, locale);
        }
@@ -121,7 +127,7 @@ public class TransBundle extends Bundle<StringId> {
        protected File getUpdateFile(String path) {
                String code = locale.toString();
                File file = null;
-               if (code.length() > 0) {
+               if (!defaultLocale && code.length() > 0) {
                        file = new File(path, name.name() + "_" + code + ".properties");
                } else {
                        // Default properties file:
@@ -191,4 +197,34 @@ public class TransBundle extends Bundle<StringId> {
 
                return locale;
        }
+
+       /**
+        * Return all the languages known by the program.
+        * 
+        * @return the known language codes
+        */
+       static public List<String> getKnownLanguages() {
+               List<String> resources = new LinkedList<String>();
+
+               String regex = ".*" + Target.resources.name()
+                               + "[_a-zA-Za]*\\.properties$";
+
+               for (String res : ResourceList.getResources(Pattern.compile(regex))) {
+                       String resource = res;
+                       int index = resource.lastIndexOf('/');
+                       if (index >= 0 && index < (resource.length() - 1))
+                               resource = resource.substring(index + 1);
+                       if (resource.startsWith(Target.resources.name())) {
+                               resource = resource.substring(0, resource.length()
+                                               - ".properties".length());
+                               resource = resource.substring(Target.resources.name().length());
+                               if (resource.startsWith("_")) {
+                                       resource = resource.substring(1);
+                                       resources.add(resource);
+                               }
+                       }
+               }
+
+               return resources;
+       }
 }
index 237c898f42ef2bbc0c90096a764b26a3d4abbf9e..c2897564388ac9a84d5750aff716789642dd9205 100644 (file)
@@ -30,7 +30,7 @@ KEY_ACTION_VIEW_CONTACT = Open
 KEY_ACTION_EDIT_CONTACT = Edit
 # (WHAT: Action key, WHERE: ContactDetails)
 # Edit the contact in RAW mode
-KEY_ACTION_EDIT_CONTACT_RAW = 
+KEY_ACTION_EDIT_CONTACT_RAW = Raw
 # (WHAT: Action key, WHERE: ContactDetailsRaw)
 # Edit the RAW field
 KEY_ACTION_EDIT_FIELD = Edit