diff --git a/components/tvplanit/source/vpbaseds.pas b/components/tvplanit/source/vpbaseds.pas index d17c4d7c6..bd06bdb3b 100644 --- a/components/tvplanit/source/vpbaseds.pas +++ b/components/tvplanit/source/vpbaseds.pas @@ -314,9 +314,9 @@ type procedure DeleteResource(Res: TVpResource); function FindResource(const AResourceName: String): TVpResource; + function FindBestCategory(const ACategoryNames: TStrings): String; function FindBestEventCategory(const ACategoryNames: TStrings): String; - function FindBestTaskCategory(const ACategoryNames: TStrings): String; - + property Connected : boolean read FConnected write SetConnected; property Loading : Boolean read FLoading write FLoading; property Resource: TVpResource read FResource write SetResource; @@ -567,7 +567,7 @@ begin end; end; -function TVpCustomDatastore.FindBestTaskCategory(const ACategoryNames: TStrings): String; +function TVpCustomDatastore.FindBestCategory(const ACategoryNames: TStrings): String; const CAT_NAMES: array[TVpCategoryType] of string = ('BUSINESS', 'CLIENTS', 'FAMILY', 'OTHER', 'PERSONAL'); var diff --git a/components/tvplanit/source/vpcontactgrid.pas b/components/tvplanit/source/vpcontactgrid.pas index d707639e2..48bc327b8 100644 --- a/components/tvplanit/source/vpcontactgrid.pas +++ b/components/tvplanit/source/vpcontactgrid.pas @@ -200,15 +200,17 @@ type procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure ScrollIntoView; + procedure EditContact; + procedure EndEdit(Sender: TObject); + + { popup menu } + function GetPopupMenu: TPopupMenu; override; + procedure InitializeDefaultPopup; procedure PopupAddContact(Sender: TObject); procedure PopupDeleteContact(Sender: TObject); procedure PopupEditContact(Sender: TObject); procedure PopupExportVCard(Sender: TObject); procedure PopupImportVCards(Sender: TObject); - procedure EditContact; - procedure EndEdit(Sender: TObject); - function GetPopupMenu: TPopupMenu; override; - procedure InitializeDefaultPopup; { message handlers } {$IFNDEF LCL} @@ -252,7 +254,7 @@ type DisplayOnly: Boolean); override; procedure ExportVCardFile(const AFileName: String; const AContacts: TVpContactArr); function ImportVCardFile(const AFileName: String; - APreview: Boolean = false): TVpContactArr; + APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpContactArr; { - Added to support the buttonbar component. } function SelectContactByName(const Name: String): Boolean; @@ -1615,14 +1617,14 @@ begin end; function TVpContactGrid.ImportVCardFile(const AFileName: String; - APreview: Boolean = false): TVpContactArr; + APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpContactArr; begin if ReadOnly or (not CheckCreateResource) or (not Assigned(Datastore)) or (not Assigned(Datastore.Resource)) then exit(nil); - Result := Datastore.Resource.Contacts.ImportVCardFile(AFileName, APreview); + Result := Datastore.Resource.Contacts.ImportVCardFile(AFileName, APreview, ADefaultCategory); if Length(Result) > 0 then begin FActiveContact := Result[High(Result)]; diff --git a/components/tvplanit/source/vpdata.pas b/components/tvplanit/source/vpdata.pas index cf546ffbb..a944e464e 100644 --- a/components/tvplanit/source/vpdata.pas +++ b/components/tvplanit/source/vpdata.pas @@ -494,7 +494,8 @@ type CaseInsensitive: Boolean = True): Integer; function GetContact(Index: Integer): TVpContact; function Last:TVpContact; - function ImportVCardFile(const AFileName: String; const APreview: Boolean = false): TVpContactArr; + function ImportVCardFile(const AFileName: String; const APreview: Boolean = false; + ADefaultCategory: Integer = -1): TVpContactArr; procedure ExportVCardFile(const AFileName: String; const AContacts: TVpContactArr); procedure Sort; @@ -555,6 +556,7 @@ type FNotes: string; //FPrivateRec: boolean; FCategory: integer; + FPickedCategory: Integer; FCustom1: string; FCustom2: string; FCustom3: string; @@ -636,6 +638,7 @@ type property Changed: Boolean read FChanged write SetChanged; property Deleted: Boolean read FDeleted write SetDeleted; property Owner: TVpContacts read FOwner write FOwner; + property PickedCategory: Integer read FPickedCategory write FPickedCategory; {$ifdef WITHRTTI} published @@ -2232,6 +2235,9 @@ var phoneIdx: Integer; phones: array[1..NUM_PHONES] of ^String; phonetypes: array[1..NUM_PHONES] of ^Integer; + datastore: TVpCustomDatastore; + cat: String; + ct: TVpCategoryType; begin phones[1] := @FPhone1; phonetypes[1] := @FPhoneType1; phones[2] := @FPhone2; phonetypes[2] := @FPhoneType2; @@ -2336,6 +2342,24 @@ begin FPosition := FPosition + '; ' + s; end; + { Category } + { tvplanit has only 1 category, vcard may have several. We pick the first one + defined by TVpCategorytype. If none is found we select ctOther. } + if ACard.PickedCategory > -1 then + FCategory := ACard.PickedCategory + else + begin + FCategory := ord(ctOther); + datastore := TVpCustomDatastore(Owner.Owner.Owner.Owner); + cat := datastore.FindBestCategory(ACard.Categories); + for ct in TVpCategoryType do + if cat = CategoryLabel(ct) then + begin + FCategory := ord(ct); + break; + end; + end; + FOwner.FOwner.ContactsDirty := true; FChanged := true; end; @@ -2906,7 +2930,7 @@ begin end; function TVpContacts.ImportVCardFile(const AFileName: String; - const APreview: Boolean = false): TVpContactArr; + const APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpContactArr; const BLOCK_SIZE = 10; var @@ -2937,6 +2961,7 @@ begin begin previewForm := TVPImportPreviewVCardForm.Create(nil); previewForm.Position := poMainFormcenter; + previewForm.Datastore := datastore; previewForm.VCards := vCards; if not previewForm.Execute then begin @@ -3043,7 +3068,7 @@ begin begin FCategory :=ord(ctOther); datastore := TVpCustomDatastore(Owner.Owner.Owner.Owner); - cat := datastore.FindBestTaskCategory(AEntry.Categories); + cat := datastore.FindBestCategory(AEntry.Categories); for ct in TVpCategoryType do if cat = CategoryLabel(ct) then begin diff --git a/components/tvplanit/source/vpimportpreview_icaltask.lfm b/components/tvplanit/source/vpimportpreview_icaltask.lfm index 805f35016..f1a4c1c60 100644 --- a/components/tvplanit/source/vpimportpreview_icaltask.lfm +++ b/components/tvplanit/source/vpimportpreview_icaltask.lfm @@ -20,13 +20,13 @@ inherited VpImportPreviewICalTaskForm: TVpImportPreviewICalTaskForm PickList.Strings = ( ) ReadOnly = True Title.Caption = 'Items' - Width = 630 + Width = 634 end> OnGetEditText = GridGetEditText OnSetEditText = GridSetEditText ColWidths = ( 33 - 630 + 634 ) end inherited ButtonPanel: TPanel diff --git a/components/tvplanit/source/vpimportpreview_icaltask.pas b/components/tvplanit/source/vpimportpreview_icaltask.pas index 4a396962b..6798b0200 100644 --- a/components/tvplanit/source/vpimportpreview_icaltask.pas +++ b/components/tvplanit/source/vpimportpreview_icaltask.pas @@ -186,7 +186,7 @@ begin for i := 0 to FItems.Count-1 do begin task := TVpICalToDo(FItems[i]); - cat := FDatastore.FindBestTaskCategory(task.Categories); + cat := FDatastore.FindBestCategory(task.Categories); if cat = '' then cat := FDefaultCategory; if cat <> '' then task.PickedCategory := Grid.Columns[2].PickList.IndexOf(cat) diff --git a/components/tvplanit/source/vpimportpreview_vcard.lfm b/components/tvplanit/source/vpimportpreview_vcard.lfm index a90254590..5dce95ef0 100644 --- a/components/tvplanit/source/vpimportpreview_vcard.lfm +++ b/components/tvplanit/source/vpimportpreview_vcard.lfm @@ -20,11 +20,13 @@ inherited VpImportPreviewVCardForm: TVpImportPreviewVCardForm PickList.Strings = ( ) ReadOnly = True Title.Caption = 'Items' - Width = 634 + Width = 630 end> + OnGetEditText = GridGetEditText + OnSetEditText = GridSetEditText ColWidths = ( 33 - 634 + 630 ) end inherited ButtonPanel: TPanel diff --git a/components/tvplanit/source/vpimportpreview_vcard.pas b/components/tvplanit/source/vpimportpreview_vcard.pas index 2dff26568..b8260bed1 100644 --- a/components/tvplanit/source/vpimportpreview_vcard.pas +++ b/components/tvplanit/source/vpimportpreview_vcard.pas @@ -6,16 +6,21 @@ interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, - VpData, VpBaseDS, VpImportPreview, VpVCard; + VpData, VpBaseDS, VpImportPreview, VpVCard, Grids; type { TVpImportPreviewVCardForm } TVpImportPreviewVCardForm = class(TVpImportPreviewForm) + procedure GridGetEditText(Sender: TObject; ACol, ARow: Integer; + var Value: string); + procedure GridSetEditText(Sender: TObject; ACol, ARow: Integer; + const Value: string); private FVCards: TVpVCards; FDatastore: TVpCustomDatastore; + FDefaultCategory: String; function GetCardText(ACard: TVpVCard): String; procedure SetVCards(const AValue: TVpVCards); @@ -29,6 +34,7 @@ type function IsChecked(ARow: Integer): Boolean; override; property VCards: TVpVCards read FVCards write SetVCards; property Datastore: TVpCustomDatastore read FDatastore write FDatastore; + property DefaultCategory: String read FDefaultCategory write FDefaultCategory; end; var @@ -63,11 +69,13 @@ var card: TVpVCard; begin Result := ''; - if (ACol = 1) and (ARow >= Grid.FixedRows) then + if (ARow >= Grid.FixedRows) then begin card := TVpVCard(FItems[ARow - Grid.FixedRows]); - if card <> nil then - Result := GetCardText(card); + case ACol of + 1: Result := GetCardText(card); + 2: Result := Grid.Columns[2].PickList[card.PickedCategory] + end; end; end; @@ -92,6 +100,30 @@ begin s := ACard.GetEMail; if s <> '' then Result := Result + LineEnding + RSEMail + ': ' + s; + + s := ACard.Categories.CommaText; + if s = '' then s := RSNoneStr; + Result := Result + LineEnding + RSCategoryLabel + ' ' + s; +end; + +procedure TVpImportPreviewVCardForm.GridGetEditText(Sender: TObject; ACol, + ARow: Integer; var Value: string); +var + card: TVpVCard; +begin + card := TVpVCard(FItems[Grid.Row - Grid.FixedRows]); + if card <> nil then + Value := Grid.Columns[2].PickList[card.PickedCategory]; +end; + +procedure TVpImportPreviewVCardForm.GridSetEditText(Sender: TObject; ACol, + ARow: Integer; const Value: string); +var + card: TVpVCard; +begin + card := TVpVCard(FItems[Grid.Row - Grid.FixedRows]); + if card <> nil then + card.PickedCategory := Grid.Columns[2].PickList.IndexOf(Value);; end; function TVpImportPreviewVCardForm.IsChecked(ARow: Integer): Boolean; @@ -109,6 +141,10 @@ end; procedure TVpImportPreviewVCardForm.PrepareItems; var i: Integer; + card: TVpVCard; + cat: string; + ct: TVpCategoryType; + L: TStrings; begin FItems.Clear; if FVCards <> nil then @@ -118,6 +154,39 @@ begin inherited; Grid.Columns[1].Title.Caption := RSContactItems; + + if (FVCards <> nil) and (FDataStore <> nil) and (Grid.Columns.Count = 2) then + begin + Grid.Columns[1].Title.Caption := RSContactItems; + + with Grid.Columns.Add do + begin + SizePriority := 0; + Width := 160; + Title.Caption := RSAssignedCategory; + ButtonStyle := cbsPickList; + L := TStringList.Create; + try + for ct in TVpCategoryType do + L.Add(CategoryLabel(ct)); + PickList.Assign(L); + finally + L.Free; + end; + end; + + for i := 0 to FItems.Count-1 do + begin + card := TVpVCard(FItems[i]); + cat := FDatastore.FindBestCategory(card.Categories); + if cat = '' then cat := FDefaultCategory; + if cat <> '' then + card.PickedCategory := Grid.Columns[2].PickList.IndexOf(cat) + else + card.PickedCategory := ord(ctOther); + end; + end; + end; procedure TVpImportPreviewVCardForm.SetVCards(const AValue: TVpVCards); diff --git a/components/tvplanit/source/vptasklist.pas b/components/tvplanit/source/vptasklist.pas index c18589f87..27a7361bd 100644 --- a/components/tvplanit/source/vptasklist.pas +++ b/components/tvplanit/source/vptasklist.pas @@ -947,14 +947,8 @@ begin dlg.FileName := ''; dlg.Options := dlg.Options + [ofAllowMultiSelect, ofFileMustExist]; if dlg.Execute then begin - Screen.Cursor := crHourGlass; - try - for fn in dlg.Files do - Datastore.Resource.Tasks.ImportICalFile(fn); - Invalidate; - finally - Screen.Cursor := crDefault; - end; + for fn in dlg.Files do + ImportICalFile(fn, dlg.Files.Count = 1); end; finally dlg.Free; diff --git a/components/tvplanit/source/vpvcard.pas b/components/tvplanit/source/vpvcard.pas index 059fd1027..5e8517caf 100644 --- a/components/tvplanit/source/vpvcard.pas +++ b/components/tvplanit/source/vpvcard.pas @@ -50,10 +50,16 @@ type FBirthDay: TDateTime; FAnniversary: TDateTime; + FCategories: TStrings; + FPickedCategory: Integer; FSkip: Boolean; + + function GetCategory(AIndex: Integer): String; + function GetCategoryCount: Integer; public constructor Create; + destructor Destroy; override; procedure Analyze; override; function FindItem(AKey, ATags: String): TVpVCardItem; @@ -93,8 +99,12 @@ type property ISDN: String read FISDN write FISDN; property Pager: String read FPager write FPager; - property BirthDay: TDateTime read FBirthday write FBirthDay; property Anniversary: TDateTime read FAnniversary write FAnniversary; + property BirthDay: TDateTime read FBirthday write FBirthDay; + property Category[AIndex: Integer]: string read GetCategory; + property CategoryCount: Integer read GetCategoryCount; + property Categories: TStrings read FCategories write FCategories; + property PickedCategory: Integer read FPickedCategory write FPickedCategory; property Version: String read FVersion; property Skip: Boolean read FSkip write FSkip; // Flag to skip import @@ -208,6 +218,15 @@ end; constructor TVpVCard.Create; begin inherited Create(TVpVCardItem); + FCategories := TStringList.Create; + FCategories.Delimiter := ','; // VCard categories are separated by comma in vcf file. + FCategories.StrictDelimiter := true; +end; + +destructor TVpVCard.Destroy; +begin + FCategories.Free; + inherited; end; procedure TVpVCard.Analyze; @@ -298,6 +317,8 @@ begin FAnniversary := dt; end; end; + 'CATEGORIES': + FCategories.CommaText := item.Value; end; end; @@ -314,6 +335,16 @@ begin Result := TVpVCardItem(inherited FindItem(AKey, ATags)); end; +function TVpVCard.GetCategory(AIndex: Integer): String; +begin + Result := FCategories[AIndex]; +end; + +function TVpVCard.GetCategoryCount: Integer; +begin + Result := FCategories.Count; +end; + function TVpVCard.GetEMail: String; begin Result := ''; @@ -417,6 +448,10 @@ begin if HomeEMail <> '' then AList.Add('EMAIL;TYPE=HOME:' + HomeEMail); + // Categories + if Categories.Count > 0 then + AList.Add('CATEGORIES:' + Categories.CommaText); + AList.Add('END:VCARD'); end;