1 /* ***** BEGIN LICENSE BLOCK *****
  2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3  *
  4  * The contents of this file are subject to the Mozilla Public License Version
  5  * 1.1 (the "License"); you may not use this file except in compliance with
  6  * the License. You may obtain a copy of the License at
  7  * http://www.mozilla.org/MPL/
  8  *
  9  * Software distributed under the License is distributed on an "AS IS" basis,
 10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 11  * for the specific language governing rights and limitations under the
 12  * License.
 13  *
 14  * The Original Code is gContactSync.
 15  *
 16  * The Initial Developer of the Original Code is
 17  * Josh Geenen <gcontactsync@pirules.org>.
 18  * Portions created by the Initial Developer are Copyright (C) 2009
 19  * the Initial Developer. All Rights Reserved.
 20  *
 21  * Contributor(s):
 22  *
 23  * Alternatively, the contents of this file may be used under the terms of
 24  * either the GNU General Public License Version 2 or later (the "GPL"), or
 25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 26  * in which case the provisions of the GPL or the LGPL are applicable instead
 27  * of those above. If you wish to allow use of your version of this file only
 28  * under the terms of either the GPL or the LGPL, and not to allow others to
 29  * use your version of this file under the terms of the MPL, indicate your
 30  * decision by deleting the provisions above and replace them with the notice
 31  * and other provisions required by the GPL or the LGPL. If you do not delete
 32  * the provisions above, a recipient may use your version of this file under
 33  * the terms of any one of the MPL, the GPL or the LGPL.
 34  *
 35  * ***** END LICENSE BLOCK ***** */
 36 
 37 if (!com) var com = {}; // A generic wrapper variable
 38 // A wrapper for all GCS functions and variables
 39 if (!com.gContactSync) com.gContactSync = {};
 40 
 41 /**
 42  * Makes a new TBContact object that has functions to get and set various values
 43  * for a contact independently of the version of Thunderbird (using com.gContactSync.GAbManager).
 44  * Optionally takes the parent directory and is able to update the card in that
 45  * directory.
 46  * 
 47  * @param aContact   {nsIAbCard}   A Thunderbird contact.
 48  * @param aDirectory {AddressBook} The parent directory.  Optional.
 49  * @class
 50  * @constructor
 51  */
 52 com.gContactSync.TBContact = function gCS_TBContact(aCard, aDirectory) {
 53   if (!(aCard instanceof Components.interfaces.nsIAbCard)) {
 54     com.gContactSync.LOGGER.LOG_ERROR("Invalid aCard passed to the TBContact constructor: " +
 55                                       aCard + "\nCalled by: " + this.caller);
 56     throw "Invalid aCard passed to TBContact";
 57   }
 58   //if (!(aDirectory instanceof com.gContactSync.AddressBook)) {
 59   //  throw "Error - invalid directory sent to the TBContact constructor";
 60   //}
 61   this.mAddressBook = aDirectory;
 62   this.mContact     = aCard;
 63   this.mPostbox     = this.mContact.setAdditionalEmailAddresses;
 64 };
 65 
 66 com.gContactSync.TBContact.prototype = {
 67   /**
 68    * Returns the value of the requested property of this contact.
 69    *
 70    * If the readOnly preference is enabled, then this will return 0 for the
 71    * LastModifiedDate.
 72    * 
 73    * @param aAttribute {string} The attribute to get (PrimaryEmail, for example)
 74    *
 75    * @returns {string} The value of the attribute, or null if not set.
 76    */
 77   getValue: function TBContact_getValue(aAttribute) {
 78     if (!aAttribute)
 79       throw "Error - invalid attribute sent to TBContact.getValue";
 80     if (aAttribute === "LastModifiedDate" && this.mAddressBook &&
 81         this.mAddressBook.mPrefs && this.mAddressBook.mPrefs.readOnly === "true") {
 82       com.gContactSync.LOGGER.VERBOSE_LOG(" * Read only mode, setting LMD to 1");
 83       return 1;
 84     }
 85     // Postbox stores additional e-mail addresses already
 86     if (this.mPostbox && (aAttribute === "ThirdEmail" || aAttribute === "FourthEmail")) {
 87       var arrLen   = {},
 88           emailArr = this.mContact.getAdditionalEmailAddresses(arrLen);
 89       if (aAttribute === "ThirdEmail" && emailArr.length > 0) {
 90         return emailArr[0];
 91       }
 92       else if (emailArr.length > 1) {
 93         return emailArr[1];
 94       }
 95       return null;
 96     }
 97     return com.gContactSync.GAbManager.getCardValue(this.mContact, aAttribute);
 98   },
 99   /**
100    * Returns the Google ID of this contact, if any, and forces it to be
101    * https://... (if present).
102    *
103    * @returns {string} The GoogleID of this contact using https
104    */
105   getID: function TBContact_getID() {
106     // get the GoogleID then force http: -> https:
107     return com.gContactSync.fixURL(this.getValue("GoogleID"));
108   },
109   /**
110    * Sets the value of the requested attribute of this contact and optionally
111    * updates the contact in its parent directory.
112    *
113    * @param aAttribute {string} The attribute to set (PrimaryEmail, for example)
114    * @param aValue     {string} The value for the given attribute.  If null the
115    *                   attribute is 'deleted' from the contact.
116    * @param aUpdate    {boolean} Set to true to update this card after setting
117    *                   the value of the attribute.
118    * @returns {boolean} True if the contact was updated.
119    */
120   setValue: function TBContact_setValue(aAttribute, aValue, aUpdate) {
121     if (this.mPostbox && (aAttribute === "ThirdEmail" || aAttribute === "FourthEmail")) {
122       // get the existing e-mail addresses
123       var arrLen   = {},
124           emailArr = this.mContact.getAdditionalEmailAddresses(arrLen);
125       if (aAttribute === "ThirdEmail") {
126         emailArr[0] = aValue;
127       }
128       // FourthEmail
129       else if (emailArr.length > 0) {
130         emailArr[1] = aValue;
131       }
132       else {
133         emailArr[0] = aValue;
134       }
135       this.mContact.setAdditionalEmailAddresses(emailArr.length, emailArr);
136     }
137     else {
138       com.gContactSync.GAbManager.setCardValue(this.mContact, aAttribute, aValue);
139     }
140     if (aUpdate)
141       return this.update();
142     return false;
143   },
144   /**
145    * Updates this card in its parent directory, if possible.
146    * @returns {boolean} True if the contact was updated.
147    */
148   update: function TBContact_update() {
149     if (!this.mAddressBook) {
150       com.gContactSync.LOGGER.LOG_WARNING("Warning - TBContact.update called w/o a directory");
151       return false;
152     }
153     return this.mAddressBook.updateContact(this);
154   },
155   /**
156    * Removes this card from its parent directory, if possible.
157    * @returns {boolean} True if the contact was removed.
158    */
159   remove: function TBContact_remove() {
160     if (!this.mAddressBook) {
161       com.gContactSync.LOGGER.LOG_WARNING("Warning - TBContact.remove called w/o a directory");
162       return false;
163     }
164     return this.mAddressBook.deleteContacts([this]);
165   },
166   /**
167    * Returns a 'name' for this contact.  It is the first non-null and not blank
168    * value for the following attributes:
169    *  - DisplayName
170    *  - PrimaryEmail
171    *  - GoogleID
172    * @returns {string} The name of this contact.
173    */
174   getName: function TBContact_getName() {
175     var displayName  = this.getValue("DisplayName");
176     if (displayName)
177       return displayName;
178     var primaryEmail = this.getValue("PrimaryEmail");
179     if (primaryEmail)
180       return primaryEmail;
181     return this.getID();
182   },
183   /**
184    * Returns true if an only if this contact has a value for one or more of the
185    * postal address fields (Address, Address2, City, State, ZipCode, or Country)
186    * of the given type (Home, Work, etc.)
187    * @param aPrefix {string} The type of address (Home, Work, etc.)
188    * @return {boolean} True if and only if one or more of the address fields of
189    *                   the given type has a value.
190    */
191   hasAddress: function TBContact_hasAddress(aPrefix) {
192     return this.getValue(aPrefix + "Address") ||
193            this.getValue(aPrefix + "Address2") ||
194            this.getValue(aPrefix + "City") ||
195            this.getValue(aPrefix + "State") ||
196            this.getValue(aPrefix + "ZipCode") ||
197            this.getValue(aPrefix + "Country");
198   }
199 };
200