Fix FN when empty (with a configurable option) + some i18n
authorNiki Roo <niki@nikiroo.be>
Mon, 28 Mar 2016 09:56:13 +0000 (11:56 +0200)
committerNiki Roo <niki@nikiroo.be>
Mon, 28 Mar 2016 09:56:13 +0000 (11:56 +0200)
src/be/nikiroo/jvcard/Contact.java
src/be/nikiroo/jvcard/Data.java
src/be/nikiroo/jvcard/launcher/Main.java
src/be/nikiroo/jvcard/resources/Trans.java
src/be/nikiroo/jvcard/resources/display.properties
src/be/nikiroo/jvcard/tui/panes/ContactDetails.java
src/be/nikiroo/jvcard/tui/panes/ContactDetailsRaw.java

index 779b60a3c596ee6ee9bcbc20b09bcf66e3d4edfd..4b46eab8afa3dcc6aa840d8c89952d0c4ef8b3b5 100644 (file)
@@ -115,7 +115,8 @@ public class Contact extends BaseClass<Data> {
         * 
         * <p>
         * The format is basically a list of field names separated by a pipe and
-        * optionally parametrised. The parameters allows you to:
+        * optionally parametrised with the 'at' (@) symbol. The parameters allows
+        * you to:
         * <ul>
         * <li>@x: show only a present/not present info</li>
         * <li>@n: limit the size to a fixed value 'n'</li>
@@ -124,6 +125,15 @@ public class Contact extends BaseClass<Data> {
         * </p>
         * 
         * <p>
+        * In case of lists or multiple-fields values, you can select a specific
+        * list or field with:
+        * <ul>
+        * <li>FIELD@(0): select the first value in a list</li>
+        * <li>FIELD@[1]: select the second field in a multiple-fields value</li>
+        * </ul>
+        * </p>
+        * 
+        * <p>
         * You can also add a fixed text if it starts with a simple-quote (').
         * </p>
         * 
@@ -157,6 +167,15 @@ public class Contact extends BaseClass<Data> {
         * </p>
         * 
         * <p>
+        * In case of lists or multiple-fields values, you can select a specific
+        * list or field with:
+        * <ul>
+        * <li>FIELD@(0): select the first value in a list</li>
+        * <li>FIELD@[1]: select the second field in a multiple-fields value</li>
+        * </ul>
+        * </p>
+        * 
+        * <p>
         * You can also add a fixed text if it starts with a simple-quote (').
         * </p>
         * 
@@ -205,6 +224,15 @@ public class Contact extends BaseClass<Data> {
         * </p>
         * 
         * <p>
+        * In case of lists or multiple-fields values, you can select a specific
+        * list or field with:
+        * <ul>
+        * <li>FIELD@(0): select the first value in a list</li>
+        * <li>FIELD@[1]: select the second field in a multiple-fields value</li>
+        * </ul>
+        * </p>
+        * 
+        * <p>
         * You can also add a fixed text if it starts with a simple-quote (').
         * </p>
         * 
@@ -273,6 +301,15 @@ public class Contact extends BaseClass<Data> {
         * </p>
         * 
         * <p>
+        * In case of lists or multiple-fields values, you can select a specific
+        * list or field with:
+        * <ul>
+        * <li>FIELD@(0): select the first value in a list</li>
+        * <li>FIELD@[1]: select the second field in a multiple-fields value</li>
+        * </ul>
+        * </p>
+        * 
+        * <p>
         * You can also add a fixed text if it starts with a simple-quote (').
         * </p>
         * 
@@ -313,6 +350,8 @@ public class Contact extends BaseClass<Data> {
                        int size = -1;
                        boolean binary = false;
                        boolean expand = false;
+                       int fieldNum = -1;
+                       int valueNum = -1;
 
                        if (field.length() > 0 && field.charAt(0) != '\''
                                        && field.contains("@")) {
@@ -326,10 +365,22 @@ public class Contact extends BaseClass<Data> {
                                        } else if (opt.equals("+")) {
                                                expand = true;
                                                numOfFieldsToExpand++;
+                                       } else if (opt.length() > 0 && opt.charAt(0) == '(') {
+                                               try {
+                                                       opt = opt.substring(1, opt.length() - 1);
+                                                       valueNum = Integer.parseInt(opt);
+                                               } catch (Exception e) {
+                                               }
+                                       } else if (opt.length() > 0 && opt.charAt(0) == '[') {
+                                               try {
+                                                       opt = opt.substring(1, opt.length() - 1);
+                                                       fieldNum = Integer.parseInt(opt);
+                                               } catch (Exception e) {
+                                               }
                                        } else {
                                                try {
                                                        size = Integer.parseInt(opt);
-                                               } catch (Exception e) {
+                                               } catch (NumberFormatException e) {
                                                }
                                        }
                                }
@@ -338,6 +389,16 @@ public class Contact extends BaseClass<Data> {
                        String value = null;
                        if (field.length() > 0 && field.charAt(0) == '\'') {
                                value = field.substring(1);
+                       } else if (valueNum >= 0) {
+                               List<String> vv = getPreferredData(field).getValues();
+                               if (valueNum < vv.size()) {
+                                       value = vv.get(valueNum);
+                               }
+                       } else if (fieldNum >= 0) {
+                               List<String> ff = getPreferredData(field).getFields();
+                               if (fieldNum < ff.size()) {
+                                       value = ff.get(fieldNum);
+                               }
                        } else {
                                value = getPreferredDataValue(field);
                        }
index d6ba628d3353fa2f1b22d0f1440790a06c268631..ba5fde5df13a9d86381b965aa1487d702ff61be8 100644 (file)
@@ -71,25 +71,33 @@ public class Data extends BaseClass<TypeInfo> {
        public String getValue() {
                return unescape(value);
        }
-       
+
+       /**
+        * Change the value of this {@link Data}
+        * 
+        * @param value
+        *            the new value
+        */
+       public void setValue(String value) {
+               setRawValue(escape(value));
+       }
+
        /**
-        * Return the RAW value of this {@link Data}
+        * Return the raw value of this {@link Data}
         * 
-        * @return the RAW value
+        * @return the raw value
         */
        public String getRawValue() {
                return value;
        }
 
        /**
-        * Change the value of this {@link Data}
+        * Change the raw value of this {@link Data}
         * 
         * @param value
-        *            the new value
+        *            the new raw value
         */
-       public void setValue(String value) {
-               value = escape(value);
-
+       public void setRawValue(String value) {
                if ((value == null && this.value != null)
                                || (value != null && !value.equals(this.value))) {
                        this.value = value;
@@ -232,11 +240,13 @@ public class Data extends BaseClass<TypeInfo> {
                        for (int i = 0; i < value.length(); i++) {
                                if (value.charAt(i) == sep
                                                && (i == 0 || value.charAt(i - 1) != '\\')) {
-                                       rep.add(value.substring(last, i - last));
+                                       rep.add(value.substring(last, i));
+                                       last = i + 1;
                                }
                        }
 
-                       rep.add(value.substring(last));
+                       if (last < value.length())
+                               rep.add(value.substring(last));
                }
 
                return rep;
index b57a0f758711af87176d90d560f78d13b7fb0eac..29cf8a699bcfde3c62d768a85a8e520077af3992 100644 (file)
@@ -7,6 +7,8 @@ import java.net.Socket;
 import java.nio.charset.Charset;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
 
 import javax.imageio.ImageIO;
 
@@ -40,6 +42,9 @@ public class Main {
        static private final int ERR_INTERNAL = 3;
        static private Trans transService;
 
+       static private String defaultFn;
+       static private boolean forceComputedFn;
+
        enum Mode {
                CONTACT_MANAGER, I18N, SERVER, LOAD_PHOTO, SAVE_PHOTO, ONLY_PHOTO,
        }
@@ -262,6 +267,9 @@ public class Main {
                        utf8();
                }
 
+               // N/FN fix information:
+               readNFN();
+
                // Error management:
                if (mode == Mode.SERVER && files.size() > 0) {
                        System.err
@@ -400,7 +408,11 @@ public class Main {
 
        /**
         * Return the {@link Card} corresponding to the given resource name -- a
-        * file or a remote jvcard URL
+        * file or a remote jvcard URL.
+        * 
+        * <p>
+        * Will also fix the FN if required (see display.properties).
+        * </p>
         * 
         * @param input
         *            a filename or a remote jvcard url with named resource (e.g.:
@@ -446,6 +458,22 @@ public class Main {
                        throw new IOException("Remoting support not available", e);
                }
 
+               // Fix the FN value
+               if (defaultFn != null) {
+                       try {
+                               for (Contact contact : card.getCard()) {
+                                       Data name = contact.getPreferredData("FN");
+                                       if (name == null || name.getValue().length() == 0
+                                                       || forceComputedFn) {
+                                               name.setValue(contact.toString(defaultFn, ""));
+                                       }
+                               }
+                       } catch (Exception e) {
+                               // sync failed -> getCard() throws.
+                               // do not update.
+                       }
+               }
+
                return card;
        }
 
@@ -536,4 +564,29 @@ public class Main {
                } catch (IllegalAccessException e) {
                }
        }
+
+       /**
+        * Read display.properties to know if we should fix the FN field when empty,
+        * or always, or never.
+        */
+       static private void readNFN() {
+               ResourceBundle map = Bundles.getBundle("display");
+               try {
+                       defaultFn = map.getString("CONTACT_DETAILS_DEFAULT_FN");
+                       if (defaultFn.trim().length() == 0)
+                               defaultFn = null;
+               } catch (MissingResourceException e) {
+                       e.printStackTrace();
+               }
+
+               try {
+                       String forceComputedFnStr = map
+                                       .getString("CONTACT_DETAILS_SHOW_COMPUTED_FN");
+                       if (forceComputedFnStr.length() > 0
+                                       && forceComputedFnStr.equalsIgnoreCase("true"))
+                               forceComputedFn = true;
+               } catch (MissingResourceException e) {
+                       e.printStackTrace();
+               }
+       }
 }
index c48d6af7907407d0036113c294ee07d11f6a0588..1fa0f116aba7fc93d55a2640da7ecf528771304e 100644 (file)
@@ -283,33 +283,31 @@ public class Trans {
                KEY_TAB, // keys
                @Meta(what = "a key to press", where = "action keys", format = "MUST BE 3 chars long", info = "Enter key")
                KEY_ENTER, //
-               @Meta(what = "", where = "", format = "", info = "")
-               KEY_ACTION_BACK, // MainWindow
-               @Meta(what = "", where = "", format = "", info = "")
+               @Meta(what = "Action key", where = "All screens except the first (KEY_ACTION_QUIT)", format = "", info = "Go back to previous screen")
+               KEY_ACTION_BACK, //
+               @Meta(what = "Action key", where = "MainWindow", format = "", info = "Get help text")
                KEY_ACTION_HELP, //
-               @Meta(what = "", where = "", format = "", info = "")
-               KEY_ACTION_VIEW_CARD, // FileList
-               @Meta(what = "", where = "", format = "", info = "")
-               KEY_ACTION_VIEW_CONTACT, // ContactList
-               @Meta(what = "", where = "", format = "", info = "")
+               @Meta(what = "Action key", where = "FileList", format = "", info = "View the selected card")
+               KEY_ACTION_VIEW_CARD, //
+               @Meta(what = "Action key", where = "ContactList", format = "", info = "View the selected contact")
+               KEY_ACTION_VIEW_CONTACT, //
+               @Meta(what = "Action key", where = "ContactDetails", format = "", info = "Edit the contact")
                KEY_ACTION_EDIT_CONTACT, //
-               @Meta(what = "", where = "", format = "", info = "")
+               @Meta(what = "Action key", where = "ContactDetails", format = "", info = "Edit the contact in RAW mode")
                KEY_ACTION_EDIT_CONTACT_RAW, //
-               @Meta(what = "", where = "", format = "", info = "")
+               @Meta(what = "Action key", where = "ContactList", format = "", info = "Save the whole card")
                KEY_ACTION_SAVE_CARD, //
-               @Meta(what = "", where = "", format = "", info = "")
+               @Meta(what = "", where = "ContactList", format = "", info = "Delete the selected contact")
                KEY_ACTION_DELETE_CONTACT, //
-               @Meta(what = "", where = "", format = "", info = "")
+               @Meta(what = "Action key", where = "ContactList", format = "", info = "Filter the displayed contacts")
                KEY_ACTION_SEARCH, //
-               @Meta(what = "", where = "", format = "", info = "we could use: ' ', ┃, │...")
+               @Meta(what = "", where = "", format = "we could use: ' ', ┃, │...", info = "Field separator")
                DEAULT_FIELD_SEPARATOR, // MainContentList
-               @Meta(what = "", where = "", format = "", info = "")
-               DEAULT_FIELD_SEPARATOR_NOUTF, //
-               @Meta(what = "", where = "", format = "", info = "")
-               KEY_ACTION_INVERT, // ContactDetails
-               @Meta(what = "", where = "", format = "", info = "")
+               @Meta(what = "Action key", where = "ContactDetails", format = "", info = "Invert the photo's colours")
+               KEY_ACTION_INVERT, //
+               @Meta(what = "Action key", where = "ContactDetails", format = "", info = "Show the photo in 'fullscreen'")
                KEY_ACTION_FULLSCREEN, //
-               @Meta(what = "", where = "", format = "", info = "")
+               @Meta(what = "Action key", where = "ContactList, ContactDetails, ContactDetailsRaw", format = "", info = "Switch between the available display formats")
                KEY_ACTION_SWITCH_FORMAT, // multi-usage
                @Meta(what = "Action key", where = "Contact list, Edit Contact", format = "", info = "Add a new contact/field")
                KEY_ACTION_ADD, //
index bdb370e52b3a0732888b90a2f6d27e8efa3f883b..3b6a0561c764706ae8e01831513d5689fbe212ad 100644 (file)
@@ -7,13 +7,18 @@
 # - @n: limit the size to a fixed value 'n'
 # - @+: expand the size of this field as much as possible
 #
+# In case of lists or multiple-fields values, you can select a specific
+# list or field with:
+# - FIELD@(0): select the first value in a list</li>
+# - FIELD@[1]: select the second field in a multiple-fields value</li>
+#
 # You can also add a fixed text if it starts with a simple-quote (').
 #
 # Example: "'Contact: |N@10|FN@20|NICK@+|PHOTO@x"
 # 
 # You can cycle through them if you have more than one
 # (in this case, separate them with a comma (',')
-CONTACT_LIST_FORMAT = NICKNAME@10|FN@+|EMAIL@30|PHOTO@x,FN@+|EMAIL@40
+CONTACT_LIST_FORMAT = NICKNAME@10|FN@+|EMAIL@30|PHOTO@x,N@[0]@20|N@[1]@+|EMAIL@40
 
 # The list of details to show in View Contact mode:
 # - Each detail (separated by a pipe "|" character) is visible on its own line
@@ -34,3 +39,7 @@ CONTACT_DETAILS_INFO = Phone:=TEL|eMail:=EMAIL
 
 # The size of the details' labels
 CONTACT_DETAILS_LABEL_WIDTH = 12
+
+CONTACT_DETAILS_DEFAULT_FN = N@[1]|' |N@[0]
+
+CONTACT_DETAILS_SHOW_COMPUTED_FN = true
index 5756c7cb1a25cd7aa6d8bde5ba379823f5455a13..aa838cb6d9339cc8d57a6e91dbefe743d827ae22 100644 (file)
@@ -35,10 +35,33 @@ public class ContactDetails extends MainContent {
        private boolean fullscreenImage;
        private Panel infoPanel;
        private Label note;
-       ResourceBundle map;
+
+       // from .properties file:
+       private int labelSize = -1;
+       private String infoFormat = "";
+       //
 
        public ContactDetails(Contact contact) {
-               map = Bundles.getBundle("display");
+               // Get the .properties info:
+               ResourceBundle map = Bundles.getBundle("display");
+
+               try {
+                       labelSize = Integer.parseInt(map
+                                       .getString("CONTACT_DETAILS_LABEL_WIDTH"));
+
+               } catch (NumberFormatException e) {
+                       e.printStackTrace();
+                       labelSize = -1;
+               } catch (MissingResourceException e) {
+                       labelSize = -1;
+               }
+
+               try {
+                       infoFormat = map.getString("CONTACT_DETAILS_INFO");
+               } catch (MissingResourceException e) {
+                       e.printStackTrace();
+               }
+               //
 
                BorderLayout blayout = new BorderLayout();
                setLayoutManager(blayout);
@@ -82,36 +105,12 @@ public class ContactDetails extends MainContent {
                        infoPanel.removeAllComponents();
 
                        String name = contact.getPreferredDataValue("FN");
-                       if (name == null || name.length() == 0) {
-                               // TODO format it ourself
-                               name = contact.getPreferredDataValue("N");
-                       }
-
                        infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NAME
                                        .createLabel(name));
                        infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
                                        .createLabel(""));
 
                        // List of infos:
-                       int labelSize = -1;
-                       try {
-                               labelSize = Integer.parseInt(map
-                                               .getString("CONTACT_DETAILS_LABEL_WIDTH"));
-
-                       } catch (NumberFormatException e) {
-                               e.printStackTrace();
-                               labelSize = -1;
-                       } catch (MissingResourceException e) {
-                               labelSize = -1;
-                       }
-
-                       String infoFormat = "";
-                       try {
-                               infoFormat = map.getString("CONTACT_DETAILS_INFO");
-                       } catch (MissingResourceException e) {
-                               e.printStackTrace();
-                       }
-
                        String[] infos = infoFormat.split("\\|");
                        for (String info : infos) {
                                // # - "=FIELD" will take the preferred value for this field
index 97fede0af7022a6c6b76ac0f56fd768ccb452a23..08cf9b8b8ceb6d7b8f27231ef22e0ff59795c67d 100644 (file)
@@ -61,7 +61,7 @@ public class ContactDetailsRaw extends MainContentList {
                        public String getDefaultAnswer() {
                                Data data = getData();
                                if (data != null) {
-                                       return data.getValue().replaceAll("\n", "\\\\n");
+                                       return data.getRawValue().replaceAll("\n", "\\\\n");
                                }
 
                                return null;
@@ -71,7 +71,7 @@ public class ContactDetailsRaw extends MainContentList {
                        public String callback(String answer) {
                                Data data = getData();
                                if (data != null) {
-                                       data.setValue(answer.replaceAll("\\\\n", "\n"));
+                                       data.setRawValue(answer.replaceAll("\\\\n", "\n"));
                                        return null;
                                }