## 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
}
}
- 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);
*
*/
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();
/**
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
this.outsideWorld = outsideWorld;
}
+ @Override
public ResourceBundle newBundle(String baseName, Locale locale,
String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
} 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 {
--- /dev/null
+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);
+ }
+ }
+}
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;
/**
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.
* instance
*/
private void setLanguage(String language) {
+ defaultLocale = (language == null || language.length() == 0);
locale = getLocaleFor(language);
map = getBundle(Target.resources, locale);
}
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:
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;
+ }
}
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