X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Fjvcard%2FContact.java;h=553ca7680f486f34b1a38e9753dff0b4f06edb99;hb=296a0b75515b3a7424b98292c87cbbf2272b73f9;hp=08d5eee0fdcfe25588d37f466293225af6c17217;hpb=a3b510ab4bf89a7a2a05f3851ffe0f030b8a78f4;p=jvcard.git diff --git a/src/be/nikiroo/jvcard/Contact.java b/src/be/nikiroo/jvcard/Contact.java index 08d5eee..553ca76 100644 --- a/src/be/nikiroo/jvcard/Contact.java +++ b/src/be/nikiroo/jvcard/Contact.java @@ -7,6 +7,7 @@ import java.util.Map; import be.nikiroo.jvcard.parsers.Format; import be.nikiroo.jvcard.parsers.Parser; +import be.nikiroo.jvcard.tui.StringUtils; /** * A contact is the information that represent a contact person or organisation. @@ -135,6 +136,29 @@ public class Contact { return Parser.toString(this, format, startingBKey); } + /** + * Return a {@link String} representation of this contact formated + * accordingly to the given format. + * + * The format is basically a list of field names separated by a pipe and + * optionally parametrised. The parameters allows you to: + * + * + * Example: "N@10|FN@20|NICK@+|PHOTO@x" + * + * @param format + * the format to use + * + * @return the {@link String} representation + */ + public String toString(String format) { + return toString(format, "|", null, -1, true, false); + } + /** * Return a {@link String} representation of this contact formated * accordingly to the given format. @@ -153,13 +177,113 @@ public class Contact { * the format to use * @param separator * the separator {@link String} to use between fields + * @param padding + * the {@link String} to use for left and right padding * @param width * a fixed width or -1 for "as long as needed" * + * @param unicode + * allow Uniode or only ASCII characters + * + * @return the {@link String} representation + */ + public String toString(String format, String separator, String padding, + int width, boolean unicode, boolean removeAccents) { + StringBuilder builder = new StringBuilder(); + + for (String str : toStringArray(format, separator, padding, width, + unicode)) { + builder.append(str); + } + + return builder.toString(); + } + + /** + * Return a {@link String} representation of this contact formated + * accordingly to the given format, part by part. + * + * The format is basically a list of field names separated by a pipe and + * optionally parametrised. The parameters allows you to: + * + * + * Example: "N@10|FN@20|NICK@+|PHOTO@x" + * + * @param format + * the format to use + * @param separator + * the separator {@link String} to use between fields + * @param padding + * the {@link String} to use for left and right padding + * @param width + * a fixed width or -1 for "as long as needed" + * + * @param unicode + * allow Uniode or only ASCII characters + * + * @return the {@link String} representation + */ + public String[] toStringArray(String format, String separator, + String padding, int width, boolean unicode) { + if (width > -1) { + int numOfFields = format.split("\\|").length; + if (separator != null) + width -= (numOfFields - 1) * separator.length(); + if (padding != null) + width -= (numOfFields) * (2 * padding.length()); + + if (width < 0) + width = 0; + } + + List str = new LinkedList(); + + boolean first = true; + for (String s : toStringArray(format, width, unicode)) { + if (!first) { + str.add(separator); + } + + if (padding != null) + str.add(padding + s + padding); + else + str.add(s); + + first = false; + } + + return str.toArray(new String[] {}); + } + + /** + * Return a {@link String} representation of this contact formated + * accordingly to the given format, part by part. + * + * The format is basically a list of field names separated by a pipe and + * optionally parametrised. The parameters allows you to: + * + * + * Example: "N@10|FN@20|NICK@+|PHOTO@x" + * + * @param format + * the format to use + * @param width + * a fixed width or -1 for "as long as needed" + * @param unicode + * allow Uniode or only ASCII characters + * * @return the {@link String} representation */ - public String toString(String format, String separator, int width) { - String str = null; + public String[] toStringArray(String format, int width, boolean unicode) { + List str = new LinkedList(); String[] formatFields = format.split("\\|"); String[] values = new String[formatFields.length]; @@ -169,22 +293,11 @@ public class Contact { int totalSize = 0; if (width == 0) { - return ""; - } - - if (width > -1 && separator != null && separator.length() > 0 - && formatFields.length > 1) { - int swidth = (formatFields.length - 1) * separator.length(); - if (swidth >= width) { - str = separator; - while (str.length() < width) { - str += separator; - } - - return str.substring(0, width); + for (int i = 0; i < formatFields.length; i++) { + str.add(""); } - width -= swidth; + return str.toArray(new String[] {}); } for (int i = 0; i < formatFields.length; i++) { @@ -215,11 +328,14 @@ public class Contact { } String value = getPreferredDataValue(field); - if (value == null) + if (value == null) { value = ""; + } else { + value = StringUtils.sanitize(value, unicode); + } if (size > -1) { - value = fixedString(value, size); + value = StringUtils.padString(value, size); } expandedFields[i] = expand; @@ -236,7 +352,7 @@ public class Contact { totalSize += value.length(); } } - + if (width > -1 && totalSize > width) { int toDo = totalSize - width; for (int i = fixedsizeFields.length - 1; toDo > 0 && i >= 0; i--) { @@ -257,7 +373,7 @@ public class Contact { totalSize = width + toDo; } - + if (width > -1 && numOfFieldsToExpand > 0) { int availablePadding = width - totalSize; @@ -269,14 +385,12 @@ public class Contact { if (expandedFields[i]) { if (remainder > 0) { values[i] = values[i] - + new String(new char[remainder]).replace( - '\0', ' '); + + StringUtils.padString("", remainder); remainder = 0; } if (padPerItem > 0) { values[i] = values[i] - + new String(new char[padPerItem]).replace( - '\0', ' '); + + StringUtils.padString("", padPerItem); } } } @@ -284,46 +398,45 @@ public class Contact { totalSize = width; } } - - for (String field : values) { - if (str == null) { - str = field; - } else { - str += separator + field; - } - } - - if (str == null) - str = ""; - if (width > -1) { - str = fixedString(str, width); + int currentSize = 0; + for (int i = 0; i < values.length; i++) { + currentSize += addToList(str, values[i], currentSize, width); } - return str; + return str.toArray(new String[] {}); } /** - * Fix the size of the given {@link String} either with space-padding or by - * shortening it. + * Add a {@link String} to the given {@link List}, but make sure it does not + * exceed the maximum size, and truncate it if needed to fit. * - * @param string - * the {@link String} to fix - * @param size - * the size of the resulting {@link String} - * - * @return the fixed {@link String} of size size + * @param list + * @param add + * @param currentSize + * @param maxSize + * @return */ - static private String fixedString(String string, int size) { - int length = string.length(); + static private int addToList(List list, String add, + int currentSize, int maxSize) { + if (add == null || add.length() == 0) { + if (add != null) + list.add(add); + return 0; + } - if (length > size) - string = string.substring(0, size); - else if (length < size) - string = string - + new String(new char[size - length]).replace('\0', ' '); + if (maxSize > -1) { + if (currentSize < maxSize) { + if (currentSize + add.length() >= maxSize) { + add = add.substring(0, maxSize - currentSize); + } + } else { + add = ""; + } + } - return string; + list.add(add); + return add.length(); } /** @@ -404,10 +517,41 @@ public class Contact { this.parent.setDirty(); } - public void setParent(Card parent) { + void setParent(Card parent) { this.parent = parent; for (Data data : datas) { data.setParent(this); } } + + /** + * Delete this {@link Contact} from its parent {@link Card} if any. + * + * @return TRUE in case of success + */ + public boolean delete() { + if (parent != null) { + List list = parent.getContactsList(); + for (int i = 0; i < list.size(); i++) { + if (list.get(i) == this) { + list.remove(i); + parent.setDirty(); + return true; + } + } + } + + return false; + } + + /** + * Notify this element and all its descendants that it is in pristine + * state (as opposed to dirty). + */ + void setPristine() { + dirty = false; + for (Data data : datas) { + data.setPristine(); + } + } }