/// <summary> /// This is overridden to allow proper comparison of vCard objects /// </summary> /// <param name="obj">The object to which this instance is compared</param> /// <returns>Returns true if the object equals this instance, false if it does not</returns> public override bool Equals(object obj) { VCard vc = obj as VCard; if (vc == null) { return(false); } // The ToString() method returns a text representation of the vCard based on all of its settings so // it's a reliable way to tell if two instances are the same. return(this == vc || this.ToString() == vc.ToString()); }
/// <summary> /// This is overridden to allow copying of the additional properties /// </summary> /// <param name="p">The PDI object from which the settings are to be copied</param> protected override void Clone(PDIObject p) { VCard o = (VCard)p; this.ClearProperties(); groupName = o.Group; fn = (FormattedNameProperty)o.FormattedName.Clone(); name = (NameProperty)o.Name.Clone(); title = (TitleProperty)o.Title.Clone(); role = (RoleProperty)o.Role.Clone(); mailer = (MailerProperty)o.Mailer.Clone(); url = (UrlProperty)o.Url.Clone(); org = (OrganizationProperty)o.Organization.Clone(); uid = (UniqueIdProperty)o.UniqueId.Clone(); bday = (BirthDateProperty)o.BirthDate.Clone(); rev = (LastRevisionProperty)o.LastRevision.Clone(); tz = (TimeZoneProperty)o.TimeZone.Clone(); geo = (GeographicPositionProperty)o.GeographicPosition.Clone(); key = (PublicKeyProperty)o.PublicKey.Clone(); photo = (PhotoProperty)o.Photo.Clone(); logo = (LogoProperty)o.Logo.Clone(); sound = (SoundProperty)o.Sound.Clone(); this.Notes.CloneRange(o.Notes); this.Addresses.CloneRange(o.Addresses); this.Labels.CloneRange(o.Labels); this.Telephones.CloneRange(o.Telephones); this.EMailAddresses.CloneRange(o.EMailAddresses); this.Agents.CloneRange(o.Agents); this.CustomProperties.CloneRange(o.CustomProperties); addProfile = o.AddProfile; mimeName = (MimeNameProperty)o.MimeName.Clone(); mimeSource = (MimeSourceProperty)o.MimeSource.Clone(); prodId = (ProductIdProperty)o.ProductId.Clone(); nickname = (NicknameProperty)o.Nickname.Clone(); sortString = (SortStringProperty)o.SortString.Clone(); classification = (ClassificationProperty)o.Classification.Clone(); categories = (CategoriesProperty)o.Categories.Clone(); }
/// <summary> /// Add a vCard to the collection /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void btnAdd_Click(object sender, EventArgs e) { using(VCardPropertiesDlg dlg = new VCardPropertiesDlg()) { if(dlg.ShowDialog() == DialogResult.OK) { VCard newVCard = new VCard(); dlg.GetValues(newVCard); // Create a unique ID for the new vCard newVCard.UniqueId.AssignNewId(true); vCards.Add(newVCard); } } }
/// <summary> /// This static method can be used to load property values into an existing instance of a single vCard /// from a string. /// </summary> /// <param name="vCardText">A set of properties for a single vCard in a string</param> /// <param name="vCard">The vCard instance into which the properties will be loaded</param> /// <remarks>The properties of the specified vCard will be cleared before the new properties are loaded /// into it.</remarks> /// <example> /// <code language="cs"> /// VCard vCard = new VCard(); /// VCardParser.ParseFromString(oneVCard, vCard); /// </code> /// <code language="vbnet"> /// Dim vCard As New VCard /// VCardParser.ParseFromString(oneVCard, vCard) /// </code> /// </example> public static void ParseFromString(string vCardText, VCard vCard) { VCardParser vcp = new VCardParser(vCard); vcp.ParseString(vCardText); }
/// <summary> /// This is implemented to handle properties as they are parsed from the data stream /// </summary> /// <param name="propertyName">The name of the property.</param> /// <param name="parameters">A string collection containing the parameters and their values. If empty, /// there are no parameters.</param> /// <param name="propertyValue">The value of the property.</param> /// <remarks><para>There may be a mixture of name/value pairs or values alone in the parameters string /// collection. It is up to the derived class to process the parameter list based on the specification /// to which it conforms. For entries that are parameter names, the entry immediately following it in /// the collection is its associated parameter value. The property name, parameter names, and their /// values may be in upper, lower, or mixed case.</para> /// /// <para>The value may be an encoded string. The properties are responsible for any decoding that may /// need to occur (i.e. base 64 encoded image data).</para></remarks> /// <exception cref="PDIParserException">This is thrown if an error is encountered while parsing the data /// stream. Refer to the and inner exceptions for information on the cause of the problem.</exception> protected override void PropertyParser(string propertyName, StringCollection parameters, string propertyValue) { SpecificationVersions version = SpecificationVersions.None; string temp, group = null; int idx; // Parse out the group name if there is one idx = propertyName.IndexOf('.'); if(idx != -1) { group = propertyName.Substring(0, idx).Trim(); propertyName = propertyName.Substring(idx + 1).Trim(); } // The last entry is always CustomProperty so scan for length minus one for(idx = 0; idx < ntv.Length - 1; idx++) if(ntv[idx].IsMatch(propertyName)) break; // An opening BEGIN:VCARD property must have been seen if(currentCard == null && ntv[idx].EnumValue != PropertyType.Begin) throw new PDIParserException(this.LineNumber, LR.GetString("ExParseNoBeginProp", "BEGIN:VCARD", propertyName)); // Handle or create the property switch(ntv[idx].EnumValue) { case PropertyType.Begin: // The value must be VCARD if(String.Compare(propertyValue.Trim(), "VCARD", StringComparison.OrdinalIgnoreCase) != 0) throw new PDIParserException(this.LineNumber, LR.GetString("ExParseUnrecognizedTagValue", ntv[idx].Name, propertyValue)); // NOTE: If serializing into an existing instance, this may not be null. If so, it is // ignored. if(currentCard == null) { currentCard = new VCard(); vCards.Add(currentCard); } currentCard.Group = group; break; case PropertyType.End: // The value must be VCARD if(String.Compare(propertyValue.Trim(), "VCARD", StringComparison.OrdinalIgnoreCase) != 0) throw new PDIParserException(this.LineNumber, LR.GetString("ExParseUnrecognizedTagValue", ntv[idx].Name, propertyValue)); // The group must match too if(currentCard.Group != group) throw new PDIParserException(this.LineNumber, LR.GetString("ExParseUnexpectedGroupTag", currentCard.Group, group)); // When done, we'll propagate the version number to all objects to make it consistent currentCard.PropagateVersion(); // The vCard is added to the collection when created so we don't have to rely on an END:VCARD // to add it. currentCard = null; break; case PropertyType.Profile: // The value must be VCARD if(String.Compare(propertyValue.Trim(), "VCARD", StringComparison.OrdinalIgnoreCase) != 0) throw new PDIParserException(this.LineNumber, LR.GetString("ExParseUnrecognizedTagValue", ntv[idx].Name, propertyValue)); currentCard.AddProfile = true; break; case PropertyType.Version: // Version must be 2.1 or 3.0 temp = propertyValue.Trim(); if(temp == "2.1") version = SpecificationVersions.vCard21; else if(temp == "3.0") version = SpecificationVersions.vCard30; else throw new PDIParserException(this.LineNumber, LR.GetString("ExParseUnrecognizedVersion", "vCard", temp)); currentCard.Version = version; break; case PropertyType.MimeName: currentCard.MimeName.EncodedValue = propertyValue; break; case PropertyType.MimeSource: currentCard.MimeSource.DeserializeParameters(parameters); currentCard.MimeSource.EncodedValue = propertyValue; break; case PropertyType.ProductId: currentCard.ProductId.EncodedValue = propertyValue; break; case PropertyType.Nickname: currentCard.Nickname.DeserializeParameters(parameters); currentCard.Nickname.EncodedValue = propertyValue; currentCard.Nickname.Group = group; break; case PropertyType.SortString: currentCard.SortString.DeserializeParameters(parameters); currentCard.SortString.EncodedValue = propertyValue; currentCard.SortString.Group = group; break; case PropertyType.Class: currentCard.Classification.EncodedValue = propertyValue; currentCard.Classification.Group = group; break; case PropertyType.Categories: currentCard.Categories.DeserializeParameters(parameters); currentCard.Categories.EncodedValue = propertyValue; currentCard.Categories.Group = group; break; case PropertyType.FormattedName: currentCard.FormattedName.DeserializeParameters(parameters); currentCard.FormattedName.EncodedValue = propertyValue; currentCard.FormattedName.Group = group; break; case PropertyType.Name: currentCard.Name.DeserializeParameters(parameters); currentCard.Name.EncodedValue = propertyValue; currentCard.Name.Group = group; break; case PropertyType.Title: currentCard.Title.DeserializeParameters(parameters); currentCard.Title.EncodedValue = propertyValue; currentCard.Title.Group = group; break; case PropertyType.Role: currentCard.Role.DeserializeParameters(parameters); currentCard.Role.EncodedValue = propertyValue; currentCard.Role.Group = group; break; case PropertyType.Mailer: currentCard.Mailer.DeserializeParameters(parameters); currentCard.Mailer.EncodedValue = propertyValue; currentCard.Mailer.Group = group; break; case PropertyType.Url: currentCard.Url.DeserializeParameters(parameters); currentCard.Url.EncodedValue = propertyValue; currentCard.Url.Group = group; break; case PropertyType.Organization: currentCard.Organization.DeserializeParameters(parameters); currentCard.Organization.EncodedValue = propertyValue; currentCard.Organization.Group = group; break; case PropertyType.UniqueId: currentCard.UniqueId.EncodedValue = propertyValue; currentCard.UniqueId.Group = group; break; case PropertyType.BirthDate: currentCard.BirthDate.DeserializeParameters(parameters); currentCard.BirthDate.EncodedValue = propertyValue; currentCard.BirthDate.Group = group; break; case PropertyType.Revision: currentCard.LastRevision.DeserializeParameters(parameters); currentCard.LastRevision.EncodedValue = propertyValue; currentCard.LastRevision.Group = group; break; case PropertyType.TimeZone: currentCard.TimeZone.DeserializeParameters(parameters); currentCard.TimeZone.EncodedValue = propertyValue; currentCard.TimeZone.Group = group; break; case PropertyType.GeographicPosition: currentCard.GeographicPosition.EncodedValue = propertyValue; currentCard.GeographicPosition.Group = group; break; case PropertyType.PublicKey: currentCard.PublicKey.DeserializeParameters(parameters); currentCard.PublicKey.EncodedValue = propertyValue; currentCard.PublicKey.Group = group; break; case PropertyType.Photo: currentCard.Photo.DeserializeParameters(parameters); currentCard.Photo.EncodedValue = propertyValue; currentCard.Photo.Group = group; break; case PropertyType.Logo: currentCard.Logo.DeserializeParameters(parameters); currentCard.Logo.EncodedValue = propertyValue; currentCard.Logo.Group = group; break; case PropertyType.Sound: currentCard.Sound.DeserializeParameters(parameters); currentCard.Sound.EncodedValue = propertyValue; currentCard.Sound.Group = group; break; case PropertyType.Note: NoteProperty n = new NoteProperty(); n.DeserializeParameters(parameters); n.EncodedValue = propertyValue; n.Group = group; currentCard.Notes.Add(n); break; case PropertyType.Address: AddressProperty a = new AddressProperty(); a.DeserializeParameters(parameters); a.EncodedValue = propertyValue; a.Group = group; currentCard.Addresses.Add(a); break; case PropertyType.Label: LabelProperty l = new LabelProperty(); l.DeserializeParameters(parameters); l.EncodedValue = propertyValue; l.Group = group; currentCard.Labels.Add(l); break; case PropertyType.Telephone: TelephoneProperty t = new TelephoneProperty(); t.DeserializeParameters(parameters); t.EncodedValue = propertyValue; t.Group = group; currentCard.Telephones.Add(t); break; case PropertyType.EMail: EMailProperty e = new EMailProperty(); e.DeserializeParameters(parameters); e.EncodedValue = propertyValue; e.Group = group; currentCard.EMailAddresses.Add(e); break; case PropertyType.Agent: AgentProperty ag = new AgentProperty(); ag.DeserializeParameters(parameters); ag.EncodedValue = propertyValue; ag.Group = group; currentCard.Agents.Add(ag); break; default: // Anything else is a custom property CustomProperty c = new CustomProperty(propertyName); c.DeserializeParameters(parameters); c.EncodedValue = propertyValue; c.Group = group; currentCard.CustomProperties.Add(c); break; } }
/// <summary> /// This version of the constructor is used when parsing vCard data that is to be stored in an existing /// vCard instance. /// </summary> /// <remarks>The properties in the passed vCard will be cleared</remarks> /// <param name="vCard">The existing vCard instance</param> /// <exception cref="ArgumentNullException">This is thrown if the specified vCard object is null</exception> protected VCardParser(VCard vCard) : this() { if(vCard == null) throw new ArgumentNullException("vCard", LR.GetString("ExParseNullObject", "vCard")); currentCard = vCard; currentCard.ClearProperties(); vCards.Add(vCard); }
/// <summary> /// Update the vCard with the dialog control values /// </summary> /// <param name="vCard">The vCard in which the settings are updated</param> public void GetValues(VCard vCard) { // Set the version based on the one selected vCard.Version = (cboVersion.SelectedIndex == 0) ? SpecificationVersions.vCard21 : SpecificationVersions.vCard30; // General properties. Unique ID is not changed. Last Revision is set to the current date and time. vCard.Classification.Value = txtClass.Text; vCard.LastRevision.DateTimeValue = DateTime.Now; // Name properties vCard.Name.FamilyName = txtLastName.Text; vCard.Name.GivenName = txtFirstName.Text; vCard.Name.AdditionalNames = txtMiddleName.Text; vCard.Name.NamePrefix = txtTitle.Text; vCard.Name.NameSuffix = txtSuffix.Text; vCard.SortString.Value = txtSortString.Text; vCard.FormattedName.Value = txtFormattedName.Text; // We'll parse nicknames as a comma separated string vCard.Nickname.NicknamesString = txtNickname.Text; // For the collections, we'll clear the existing items and copy the modified items from the browse // control binding sources. // Addresses vCard.Addresses.Clear(); vCard.Addresses.CloneRange((AddressPropertyCollection)ucAddresses.BindingSource.DataSource); // Labels vCard.Labels.Clear(); vCard.Labels.CloneRange((LabelPropertyCollection)ucLabels.BindingSource.DataSource); // Phone/E-Mail vCard.Telephones.Clear(); vCard.Telephones.CloneRange((TelephonePropertyCollection)ucPhones.BindingSource.DataSource); vCard.EMailAddresses.Clear(); vCard.EMailAddresses.CloneRange((EMailPropertyCollection)ucEMail.BindingSource.DataSource); // Work vCard.Organization.Name = txtOrganization.Text; vCard.Title.Value = txtJobTitle.Text; vCard.Role.Value = txtRole.Text; // We'll parse units and categories as comma separated strings vCard.Organization.UnitsString = txtUnits.Text; vCard.Categories.CategoriesString = txtCategories.Text; // Other if(!dtpBirthDate.Checked) vCard.BirthDate.DateTimeValue = DateTime.MinValue; else { vCard.BirthDate.DateTimeValue = dtpBirthDate.Value; // Store time too if it isn't midnight if(dtpBirthDate.Value != dtpBirthDate.Value.Date) vCard.BirthDate.ValueLocation = ValLocValue.DateTime; else vCard.BirthDate.ValueLocation = ValLocValue.Date; } // See if the new value is just an offset. If so, set the value type to UTC Offset. try { if(txtTimeZone.Text.Trim().Length == 0) { vCard.TimeZone.ValueLocation = ValLocValue.Text; vCard.TimeZone.Value = String.Empty; } else { vCard.TimeZone.TimeSpanValue = DateUtils.FromISO8601TimeZone( txtTimeZone.Text); vCard.TimeZone.ValueLocation = ValLocValue.UtcOffset; } } catch { vCard.TimeZone.ValueLocation = ValLocValue.Text; vCard.TimeZone.Value = txtTimeZone.Text; } if(txtLatitude.Text.Trim().Length != 0 || txtLongitude.Text.Trim().Length != 0) { vCard.GeographicPosition.Latitude = Convert.ToDouble(txtLatitude.Text, CultureInfo.CurrentCulture); vCard.GeographicPosition.Longitude = Convert.ToDouble(txtLongitude.Text, CultureInfo.CurrentCulture); } else vCard.GeographicPosition.Latitude = vCard.GeographicPosition.Longitude = 0.0F; vCard.Url.Value = txtWebPage.Text; if(txtComments.Text.Length != 0) { if(vCard.Notes.Count != 0) vCard.Notes[0].Value = txtComments.Text; else vCard.Notes.Add(txtComments.Text); } else if(vCard.Notes.Count != 0) vCard.Notes.RemoveAt(0); // Photo if(ucPhoto.IsInline) { vCard.Photo.ValueLocation = ValLocValue.Binary; vCard.Photo.SetImageBytes(ucPhoto.GetImageBytes()); vCard.Photo.ImageType = ucPhoto.ImageType; } else { vCard.Photo.ValueLocation = ValLocValue.Uri; vCard.Photo.Value = ucPhoto.ImageFilename; vCard.Photo.ImageType = ucPhoto.ImageType; } // Logo if(ucLogo.IsInline) { vCard.Logo.ValueLocation = ValLocValue.Binary; vCard.Logo.SetImageBytes(ucLogo.GetImageBytes()); vCard.Logo.ImageType = ucLogo.ImageType; } else { vCard.Logo.ValueLocation = ValLocValue.Uri; vCard.Logo.Value = ucLogo.ImageFilename; vCard.Logo.ImageType = ucLogo.ImageType; } }
/// <summary> /// Initialize the dialog controls using the specified vCard /// </summary> /// <param name="vCard">The vCard from which to get the settings</param> public void SetValues(VCard vCard) { // Enable or disable fields based on the version cboVersion.SelectedIndex = (vCard.Version == SpecificationVersions.vCard21) ? 0 : 1; // General properties txtUniqueId.Text = vCard.UniqueId.Value; txtClass.Text = vCard.Classification.Value; txtLastRevised.Text = vCard.LastRevision.DateTimeValue.ToString("G"); // Name properties txtLastName.Text = vCard.Name.FamilyName; txtFirstName.Text = vCard.Name.GivenName; txtMiddleName.Text = vCard.Name.AdditionalNames; txtTitle.Text = vCard.Name.NamePrefix; txtSuffix.Text = vCard.Name.NameSuffix; txtSortString.Text = vCard.SortString.Value; txtFormattedName.Text = vCard.FormattedName.Value; // We'll edit nicknames as a comma separated string txtNickname.Text = vCard.Nickname.NicknamesString; // We could bind directly to the existing collections but that would modify them. To preserve the // original items, we'll pass a copy of the collections instead. // Addresses ucAddresses.BindingSource.DataSource = new AddressPropertyCollection().CloneRange(vCard.Addresses); // Labels ucLabels.BindingSource.DataSource = new LabelPropertyCollection().CloneRange(vCard.Labels); // Phone/E-Mail ucPhones.BindingSource.DataSource = new TelephonePropertyCollection().CloneRange(vCard.Telephones); ucEMail.BindingSource.DataSource = new EMailPropertyCollection().CloneRange(vCard.EMailAddresses); // Work txtOrganization.Text = vCard.Organization.Name; txtJobTitle.Text = vCard.Title.Value; txtRole.Text = vCard.Role.Value; // We'll edit units and categories as comma separated strings txtUnits.Text = vCard.Organization.UnitsString; txtCategories.Text = vCard.Categories.CategoriesString; // Other if(vCard.BirthDate.DateTimeValue == DateTime.MinValue) dtpBirthDate.Checked = false; else { dtpBirthDate.Value = vCard.BirthDate.DateTimeValue; dtpBirthDate.Checked = true; } txtTimeZone.Text = vCard.TimeZone.Value; txtLatitude.Text = vCard.GeographicPosition.Latitude.ToString(); txtLongitude.Text = vCard.GeographicPosition.Longitude.ToString(); txtWebPage.Text = vCard.Url.Value; // We'll only edit the first note. Chances are there won't be more than one unless grouping is used. if(vCard.Notes.Count != 0) txtComments.Text = vCard.Notes[0].Value; // Photo if(vCard.Photo.Value != null) if(vCard.Photo.ValueLocation == ValLocValue.Binary) { ucPhoto.SetImageBytes(vCard.Photo.GetImageBytes()); ucPhoto.IsInline = true; } else ucPhoto.ImageFilename = vCard.Photo.Value; ucPhoto.ImageType = vCard.Photo.ImageType; // Logo if(vCard.Logo.Value != null) if(vCard.Logo.ValueLocation == ValLocValue.Binary) { ucLogo.SetImageBytes(vCard.Logo.GetImageBytes()); ucLogo.IsInline = true; } else ucLogo.ImageFilename = vCard.Logo.Value; ucLogo.ImageType = vCard.Logo.ImageType; }
//===================================================================== /// <summary> /// This is overridden to allow cloning of a PDI object /// </summary> /// <returns>A clone of the object</returns> public override object Clone() { VCard o = new VCard(); o.Clone(this); return o; }
/// <summary> /// This is an example of sorting a vCard collection /// </summary> /// <param name="x">The first vCard</param> /// <param name="y">The second vCard</param> /// <returns>0 if equal, -1 if x is less than y, or 1 if x is greater than y</returns> /// <remarks>Due to the variety of properties in a vCard, sorting is left up to the developer utilizing a /// comparison delegate. This example sorts the collection by the name property taking into account the /// SortStringProperty if set.</remarks> private int VCardSorter(VCard x, VCard y) { string sortName1, sortName2; // Get the names to compare. Precedence is given to the SortStringProperty as that is the purpose // of its existence. sortName1 = x.SortString.Value; if(String.IsNullOrWhiteSpace(sortName1)) sortName1 = x.Name.SortableName; sortName2 = y.SortString.Value; if(String.IsNullOrWhiteSpace(sortName2)) sortName2 = y.Name.SortableName; // For descending order, change this to compare name 2 to name 1 instead. return String.Compare(sortName1, sortName2, StringComparison.CurrentCulture); }