diff --git a/components/tvplanit/languages/vpsr.de.po b/components/tvplanit/languages/vpsr.de.po index 073dfaa89..456d905f2 100644 --- a/components/tvplanit/languages/vpsr.de.po +++ b/components/tvplanit/languages/vpsr.de.po @@ -559,6 +559,14 @@ msgstr "Stunden" msgid "iCalendar files (*.ical;*.ics)|*.ical;*.ics" msgstr "iCalendar Dateien ('*.ical;*.ics)|*.ical;*.ics" +#: vpsr.rsimporticalevent +msgid "Import ICalendar Event" +msgstr "" + +#: vpsr.rsimporticaltask +msgid "Import ICalendar Task" +msgstr "" + #: vpsr.rsinches msgid "Inches" msgstr "Zoll" @@ -1753,3 +1761,4 @@ msgstr "Unbekannte Achsen-Spezifikation: %s" #: vpsr.sxmldecnotatbeg msgid "The XML declaration must appear before the first element" msgstr "Die XML-Deklaration muss vor dem ersten Element erscheinen" + diff --git a/components/tvplanit/languages/vpsr.en.po b/components/tvplanit/languages/vpsr.en.po index 0c46509b8..daf4a5c90 100644 --- a/components/tvplanit/languages/vpsr.en.po +++ b/components/tvplanit/languages/vpsr.en.po @@ -553,6 +553,14 @@ msgstr "Hours" msgid "iCalendar files (*.ical;*.ics)|*.ical;*.ics" msgstr "iCalendar files (*.ical;*.ics)|*.ical;*.ics" +#: vpsr.rsimporticalevent +msgid "Import ICalendar Event" +msgstr "" + +#: vpsr.rsimporticaltask +msgid "Import ICalendar Task" +msgstr "" + #: vpsr.rsinches msgid "Inches" msgstr "Inches" @@ -1734,3 +1742,4 @@ msgstr "Unknown axis specifier: %s" #: vpsr.sxmldecnotatbeg msgid "The XML declaration must appear before the first element" msgstr "The XML declaration must appear before the first element" + diff --git a/components/tvplanit/languages/vpsr.fi.po b/components/tvplanit/languages/vpsr.fi.po index bb4b73400..718728320 100644 --- a/components/tvplanit/languages/vpsr.fi.po +++ b/components/tvplanit/languages/vpsr.fi.po @@ -550,6 +550,14 @@ msgstr "Tunnit" msgid "iCalendar files (*.ical;*.ics)|*.ical;*.ics" msgstr "" +#: vpsr.rsimporticalevent +msgid "Import ICalendar Event" +msgstr "" + +#: vpsr.rsimporticaltask +msgid "Import ICalendar Task" +msgstr "" + #: vpsr.rsinches msgid "Inches" msgstr "" diff --git a/components/tvplanit/languages/vpsr.fr.po b/components/tvplanit/languages/vpsr.fr.po index c1625901f..a0e534e54 100644 --- a/components/tvplanit/languages/vpsr.fr.po +++ b/components/tvplanit/languages/vpsr.fr.po @@ -565,6 +565,14 @@ msgstr "Heures" msgid "iCalendar files (*.ical;*.ics)|*.ical;*.ics" msgstr "" +#: vpsr.rsimporticalevent +msgid "Import ICalendar Event" +msgstr "" + +#: vpsr.rsimporticaltask +msgid "Import ICalendar Task" +msgstr "" + #: vpsr.rsinches msgid "Inches" msgstr "" diff --git a/components/tvplanit/languages/vpsr.nl.po b/components/tvplanit/languages/vpsr.nl.po index 040f5fdac..f9c27dd15 100644 --- a/components/tvplanit/languages/vpsr.nl.po +++ b/components/tvplanit/languages/vpsr.nl.po @@ -559,6 +559,14 @@ msgstr "Uren" msgid "iCalendar files (*.ical;*.ics)|*.ical;*.ics" msgstr "" +#: vpsr.rsimporticalevent +msgid "Import ICalendar Event" +msgstr "" + +#: vpsr.rsimporticaltask +msgid "Import ICalendar Task" +msgstr "" + #: vpsr.rsinches msgid "Inches" msgstr "" diff --git a/components/tvplanit/languages/vpsr.pl.po b/components/tvplanit/languages/vpsr.pl.po index e9b472690..7e51d9975 100644 --- a/components/tvplanit/languages/vpsr.pl.po +++ b/components/tvplanit/languages/vpsr.pl.po @@ -559,6 +559,14 @@ msgstr "Godziny" msgid "iCalendar files (*.ical;*.ics)|*.ical;*.ics" msgstr "Pliki iCalendar (*.ical;*.ics)|*.ical;*.ics" +#: vpsr.rsimporticalevent +msgid "Import ICalendar Event" +msgstr "" + +#: vpsr.rsimporticaltask +msgid "Import ICalendar Task" +msgstr "" + #: vpsr.rsinches msgid "Inches" msgstr "Cale" diff --git a/components/tvplanit/languages/vpsr.pot b/components/tvplanit/languages/vpsr.pot index 470e9218d..3461b3b4c 100644 --- a/components/tvplanit/languages/vpsr.pot +++ b/components/tvplanit/languages/vpsr.pot @@ -543,6 +543,14 @@ msgstr "" msgid "iCalendar files (*.ical;*.ics)|*.ical;*.ics" msgstr "" +#: vpsr.rsimporticalevent +msgid "Import ICalendar Event" +msgstr "" + +#: vpsr.rsimporticaltask +msgid "Import ICalendar Task" +msgstr "" + #: vpsr.rsinches msgid "Inches" msgstr "" diff --git a/components/tvplanit/languages/vpsr.ru.po b/components/tvplanit/languages/vpsr.ru.po index 2987c2efa..80e486ec1 100644 --- a/components/tvplanit/languages/vpsr.ru.po +++ b/components/tvplanit/languages/vpsr.ru.po @@ -559,6 +559,14 @@ msgstr "Часы" msgid "iCalendar files (*.ical;*.ics)|*.ical;*.ics" msgstr "" +#: vpsr.rsimporticalevent +msgid "Import ICalendar Event" +msgstr "" + +#: vpsr.rsimporticaltask +msgid "Import ICalendar Task" +msgstr "" + #: vpsr.rsinches msgid "Inches" msgstr "Дюймы" diff --git a/components/tvplanit/laz_visualplanit.lpk b/components/tvplanit/laz_visualplanit.lpk index b2241e9b6..dc78aa752 100644 --- a/components/tvplanit/laz_visualplanit.lpk +++ b/components/tvplanit/laz_visualplanit.lpk @@ -32,7 +32,7 @@ Portions created by TurboPower Software Inc. are Copyright (C) 2002 TurboPower S Contributor(s): "/> - + @@ -282,9 +282,17 @@ Contributor(s): "/> - - + + + + + + + + + + diff --git a/components/tvplanit/source/include/vpsr.inc b/components/tvplanit/source/include/vpsr.inc index e03b75035..047d133db 100644 --- a/components/tvplanit/source/include/vpsr.inc +++ b/components/tvplanit/source/include/vpsr.inc @@ -182,6 +182,8 @@ resourcestring RSOverlayedEvent = 'overlayed'; RSOverlayed = 'Overlayed'; RSICalFilter = 'iCalendar files (*.ical;*.ics)|*.ical;*.ics'; + RSImportICalEvent = 'Import ICalendar Event'; + RSImportICalTask = 'Import ICalendar Task'; RSRepeat = 'Repeat:'; RSNoEventItemsFoundInICAL = 'No event items found in "%s".'; RSNoTaskItemsFoundInICAL = 'No task items found in "%s".'; diff --git a/components/tvplanit/source/vpdata.pas b/components/tvplanit/source/vpdata.pas index 56a99deae..1651ec407 100644 --- a/components/tvplanit/source/vpdata.pas +++ b/components/tvplanit/source/vpdata.pas @@ -711,7 +711,8 @@ implementation uses Math, DateUtils, - VpException, VpConst, VpMisc, VpBaseDS, VpICalPreview; + VpException, VpConst, VpMisc, VpBaseDS, + VpImportPreview_ICalEvent, VpImportPreview_ICalTask; const TIME_EPS = 1.0 / SecondsInDay; // Epsilon for comparing times @@ -1754,7 +1755,7 @@ var event: TVpEvent; eventCounter: Integer; datastore: TVpCustomDatastore; - previewForm: TVpIcalPreviewForm = nil; + previewForm: TVpImportPreviewICalEventForm = nil; begin Result := nil; SetLength(Result, BLOCK_SIZE); @@ -1771,9 +1772,8 @@ begin end; if APreview then begin - previewForm := TVpICalPreviewForm.Create(nil); + previewForm := TVpImportPreviewICalEventForm.Create(nil); previewForm.Position := poMainFormCenter; - previewForm.Kind := icEvent; previewForm.Calendar := ical; previewForm.Datastore := datastore; if ADefaultCategory <> -1 then @@ -3008,7 +3008,7 @@ var task: TVpTask; taskCounter: Integer; datastore: TVpCustomDatastore; - previewForm: TVpICalPreviewForm = nil; + previewForm: TVpImportPreviewICalTaskForm = nil; begin Result := nil; SetLength(Result, BLOCK_SIZE); @@ -3026,9 +3026,8 @@ begin end; if APreview then begin - previewForm := TVpICalPreviewForm.Create(nil); + previewForm := TVpImportPreviewICalTaskForm.Create(nil); previewForm.Position := poMainFormCenter; - previewForm.Kind := icToDo; previewForm.Calendar := ical; previewForm.Datastore := datastore; if ADefaultCategory <> -1 then diff --git a/components/tvplanit/source/vpical.pas b/components/tvplanit/source/vpical.pas index e25a434d1..20098341f 100644 --- a/components/tvplanit/source/vpical.pas +++ b/components/tvplanit/source/vpical.pas @@ -10,8 +10,6 @@ uses type TVpICalendar = class; - TVpIcalItemKind = (icEvent, icToDo); - TVpICalItem = class(TVpFileItem) public function GetAttribute(AName: String): string; diff --git a/components/tvplanit/source/vpicalpreview.pas b/components/tvplanit/source/vpicalpreview.pas deleted file mode 100644 index e9e6570e0..000000000 --- a/components/tvplanit/source/vpicalpreview.pas +++ /dev/null @@ -1,338 +0,0 @@ -unit VpIcalPreview; - -{$mode ObjFPC}{$H+} - -interface - -uses LazLogger, - Classes, SysUtils, Types, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, - Grids, - VpData, VpIcal, VpBaseDS; - -type - - { TVpICalPreviewForm } - - TVpICalPreviewForm = class(TForm) - Button1: TButton; - Button2: TButton; - Panel1: TPanel; - Grid: TDrawGrid; - procedure GridDrawCell(Sender: TObject; aCol, aRow: Integer; aRect: TRect; - aState: TGridDrawState); - procedure GridGetCheckboxState(Sender: TObject; ACol, ARow: Integer; - var Value: TCheckboxState); - procedure GridPrepareCanvas(sender: TObject; aCol, aRow: Integer; - aState: TGridDrawState); - procedure GridSetCheckboxState(Sender: TObject; ACol, ARow: Integer; - const Value: TCheckboxState); - procedure SetCalendar(const AValue: TVpICalendar); - procedure SetKind(const AValue: TVpICalItemKind); - private - FCalendar: TVpICalendar; - FDatastore: TVpCustomDatastore; - FDefaultCategory: String; - FKind: TVpICalItemKind; - FTimeFormat: String; - FItems: TFPList; - procedure CalcRowHeights; - function GetCellText(ACol, ARow: Integer): String; - function GetEventText(AEvent: TVpICalEvent): String; - function GetToDoText(AToDo: TVpICalToDo): String; - procedure PrepareItems; - - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - function Execute: Boolean; - property Calendar: TVpICalendar read FCalendar write SetCalendar; - property Datastore: TVpCustomDatastore read FDatastore write FDatastore; - property DefaultCategory: String read FDefaultCategory write FDefaultCategory; - property Kind: TVpICalItemKind read FKind write SetKind; - - end; - -var - VpICalPreviewForm: TVpICalPreviewForm; - -implementation - -{$R *.lfm} - -uses - LCLIntf, LCLType, vpsr; - -constructor TVpICalPreviewForm.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - FItems := TFPList.Create; - FTimeFormat := 'c'; // short date + long time format -end; - -destructor TVpICalPreviewForm.Destroy; -begin - FItems.Free; - inherited Destroy; -end; - -procedure TVpICalPreviewForm.CalcRowHeights; -var - bmp: TBitmap; - row: Integer; - R: TRect; - flags: Integer; - s: String; -begin - flags := DT_CALCRECT + DT_WORDBREAK; - bmp := TBitmap.Create; - try - bmp.SetSize(1, 1); - bmp.Canvas.Font := Grid.Font; - for row := 1 to Grid.RowCount-1 do - begin - R := Rect(0, 0, MaxInt, 0); - s := GetCellText(1, row); - DrawText(bmp.Canvas.Handle, PChar(s), Length(s), R, flags); - Grid.RowHeights[row] := R.Bottom - R.Top + 2*varCellPadding; - end; - finally - bmp.Free; - end; -end; - -function TVpICalPreviewForm.Execute: Boolean; -begin - Result := ShowModal = mrOK; -end; - -function TVpICalPreviewForm.GetCellText(ACol, ARow: Integer): String; -var - item: TVpICalEntry; -begin - Result := ''; - if ARow < Grid.FixedRows then - exit; - item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); - if item = nil then - exit; - case ACol of - 1: case Kind of - icEvent: Result := GetEventText(TVpICalEvent(item)); - icToDo: Result := GetToDoText(TVpICalToDo(item)); - end; - end; -end; - -function TVpICalPreviewForm.GetEventText(AEvent: TVpICalEvent): String; -var - startTime, endTime: TDateTime; - sStartTime, sEndTime: String; - advTime: Integer; - advTimeUnits: TVpAlarmAdvType; - dingPath: String; - s: String; - cat: String; -begin - startTime := AEvent.StartTime[false]; - endTime := AEvent.EndTime[false]; - sStartTime := FormatDateTime(FTimeFormat, startTime); - sEndTime := FormatDateTime(FTimeFormat, endTime); - if TVpEvent.IsAllDayEvent(startTime, endTime) then - begin - if trunc(startTime) = trunc(endTime) then - Result := Format('%s (%s)', [sStartTime, RSAllDay]) - else - Result := Format('%s - %s (%s)', [sStartTime, sEndTime, RSAllDay]); - end else - Result := - RSStartTimeLbl + ' ' + sStartTime + LineEnding + - RSEndTimeLbl + ' ' + sEndTime; - - Result := Result + LineEnding + - RSDescriptionLbl + ' ' + AEvent.Summary + LineEnding + - RSCategoryLbl + ' '; - - // Categories - if Assigned(FDatastore) then - begin - cat := FDatastore.FindBestEventCategory(AEvent.Categories); - if cat = '' then cat := FDefaultCategory; - Result := Result + cat; - end; - - // Recurrence - if AEvent.RecurrenceFrequency <> '' then - begin - s := ''; - case Uppercase(AEvent.RecurrenceFrequency) of - 'YEARLY': - if AEvent.RecurrenceInterval in [0, 1] then - s := Format(RSYearlyOn, [FormatDateTime('dd/mm',startTime)]) - else - s := Format(RSEveryYearsOn, [AEvent.RecurrenceInterval, FormatDateTime('dd/mm', startTime)]); - 'MONTHLY': - if AEvent.RecurrenceInterval in [0, 1] then - s := Format(RSMonthlyOn, [FormatDateTime('d', startTime)]) - else - s := Format(RSEveryMonthsOn, [AEvent.RecurrenceInterval, FormatDateTime('d', startTime)]); - 'WEEKLY': - if AEvent.RecurrenceInterval in [0, 1] then - s := Format(RSWeeklyOn, [FormatDateTime('dddd',startTime)]) - else - s := Format(RSEveryWeeksOn, [AEvent.RecurrenceInterval, FormatDateTime('ddd', startTime)]); - 'DAILY': - if AEvent.RecurrenceInterval in [0, 1] then - s := RSDaily - else - s := Format(RSEveryDays, [AEvent.RecurrenceInterval]); - end; - if s <> '' then - Result := Result + LineEnding + RSRepeat + ' ' + s; - end; - - // Alarm - if AEvent.Alarm <> nil then - begin - TVpEvent.GetAlarmParams(AEvent.Alarm.Trigger, advTime, advTimeUnits); - dingPath := AEvent.Alarm.AudioSrc; - if advTime <> 1 then - begin - case advTimeUnits of - atMinutes: s := Format(RSXMinutes, [advTime]); - atHours: s := Format(RSXHours, [advTime]); - atDays: s := Format(RSXDays, [advTime]); - end; - s := Format(RSAlarmIn, [s]); - end else - case advTimeUnits of - atMinutes: s := Format(RSAlarmIn, [RS1Minute]); - atHours: s := Format(RSAlarmIn, [RS1Hour]); - atDays: s := Format(RSAlarmIn, [RS1Day]); - end; - Result := Result + LineEnding + s; - if FileExists(dingPath) then - Result := Format('%s, %s: %s', [Result, RSSound, dingPath]); - end else - Result := Result + LineEnding + RSNoAlarm; -end; - -function TVpICalPreviewForm.GetToDoText(AToDo: TVpICalToDo): String; -var - s: String; - cat: String; -begin - Result := RSDescriptionLbl + ' ' + AToDo.Summary + LineEnding + - RSDueDateLabel + ' ' + FormatDateTime(FTimeFormat, AToDo.DueTime[false]) + LineEnding + - RSCreatedOn + ' ' + FormatDateTime(FTimeFormat, AToDo.StartTime[false]); - - case TVpTask.GetTaskPriority(AToDo.Priority) of - tpLow: s := RSLow; - tpNormal: s := RSNormal; - tpHigh: s := RSHigh; - end; - Result := Result + LineEnding + RSPriorityLabel + ' ' + s + LineEnding + RSCategoryLabel + ' '; - - if Assigned(FDatastore) then - begin - cat := FDatastore.FindBestTaskCategory(AToDo.Categories); - if cat = '' then cat := FDefaultCategory; - Result := Result + cat; - end; -end; - -procedure TVpICalPreviewForm.GridDrawCell(Sender: TObject; aCol, aRow: Integer; - aRect: TRect; aState: TGridDrawState); -var - s: String; - R: TRect; -begin - R := ARect; - InflateRect(R, -varCellPadding, - varCellPadding); - s := GetCellText(ACol, ARow); - Grid.Canvas.TextRect(R, R.Left, R.Top, s); -end; - -procedure TVpICalPreviewForm.GridGetCheckboxState(Sender: TObject; ACol, - ARow: Integer; var Value: TCheckboxState); -var - item: TVpICalEntry; -begin - if ARow < Grid.FixedRows then - exit; - item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); - if item = nil then - exit; - if item.Skip then - Value := cbUnchecked - else - Value := cbChecked; -end; - -procedure TVpICalPreviewForm.GridPrepareCanvas(sender: TObject; aCol, - aRow: Integer; aState: TGridDrawState); -var - ts: TTextStyle; -begin - if ACol = 1 then - begin - ts := Grid.Canvas.TextStyle; - ts.SingleLine := false; - ts.Wordbreak := true; - Grid.Canvas.TextStyle := ts; - end; -end; - -procedure TVpICalPreviewForm.GridSetCheckboxState(Sender: TObject; ACol, - ARow: Integer; const Value: TCheckboxState); -var - item: TVpICalEntry; -begin - if ARow < Grid.FixedRows then - exit; - item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); - if item = nil then - exit; - item.Skip := (Value <> cbChecked); -end; - -procedure TVpICalPreviewForm.PrepareItems; -var - i: Integer; -begin - FItems.Clear; - if FCalendar <> nil then - begin - case FKind of - icEvent: - for i := 0 to FCalendar.Count-1 do - if (FCalendar.Entry[i] is TVpICalEvent) then - FItems.Add(FCalendar.Entry[i]); - icToDo: - for i := 0 to FCalendar.Count-1 do - if (FCalendar.Entry[i] is TVpICalToDo) then - FItems.Add(FCalendar.Entry[i]); - end; - Grid.RowCount := Grid.FixedRows + FItems.Count; - CalcRowHeights; - end else - Grid.RowCount := Grid.FixedRows; -end; - -procedure TVpICalPreviewForm.SetCalendar(const AValue: TVpICalendar); -begin - if AValue = FCalendar then - exit; - FCalendar := AValue; - PrepareItems; -end; - -procedure TVpICalPreviewForm.SetKind(const AValue: TVpICalItemKind); -begin - if AValue = FKind then - exit; - FKind := AValue; - PrepareItems; -end; - -end. - diff --git a/components/tvplanit/source/vpimportpreview.lfm b/components/tvplanit/source/vpimportpreview.lfm new file mode 100644 index 000000000..8db4e9bf3 --- /dev/null +++ b/components/tvplanit/source/vpimportpreview.lfm @@ -0,0 +1,82 @@ +object VpImportPreviewForm: TVpImportPreviewForm + Left = 327 + Height = 295 + Top = 127 + Width = 603 + Caption = 'VpImportPreviewForm' + ClientHeight = 295 + ClientWidth = 603 + object Grid: TDrawGrid + Left = 0 + Height = 258 + Top = 0 + Width = 603 + Align = alClient + AutoFillColumns = True + ColCount = 2 + Columns = < + item + Alignment = taCenter + ButtonStyle = cbsCheckboxColumn + SizePriority = 0 + Title.Caption = '' + Width = 33 + end + item + ReadOnly = True + Title.Caption = 'Items' + Width = 566 + end> + ExtendedSelect = False + FixedCols = 0 + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goEditing, goThumbTracking, goSmoothScroll] + TabOrder = 0 + OnDrawCell = GridDrawCell + OnGetCheckboxState = GridGetCheckboxState + OnPrepareCanvas = GridPrepareCanvas + OnSetCheckboxState = GridSetCheckboxState + ColWidths = ( + 33 + 566 + ) + end + object ButtonPanel: TPanel + Left = 6 + Height = 25 + Top = 264 + Width = 591 + Align = alBottom + AutoSize = True + BorderSpacing.Around = 6 + BevelOuter = bvNone + ClientHeight = 25 + ClientWidth = 591 + TabOrder = 1 + object btnExecute: TButton + AnchorSideTop.Control = ButtonPanel + AnchorSideRight.Control = btnCancel + Left = 375 + Height = 25 + Top = 0 + Width = 141 + Anchors = [akTop, akRight] + AutoSize = True + Caption = 'Import checked items' + ModalResult = 1 + TabOrder = 0 + end + object btnCancel: TButton + AnchorSideTop.Control = ButtonPanel + AnchorSideRight.Control = ButtonPanel + AnchorSideRight.Side = asrBottom + Left = 516 + Height = 25 + Top = 0 + Width = 75 + Anchors = [akTop, akRight] + Caption = 'Cancel' + ModalResult = 2 + TabOrder = 1 + end + end +end diff --git a/components/tvplanit/source/vpimportpreview.lrj b/components/tvplanit/source/vpimportpreview.lrj new file mode 100644 index 000000000..17f507e89 --- /dev/null +++ b/components/tvplanit/source/vpimportpreview.lrj @@ -0,0 +1,7 @@ +{"version":1,"strings":[ +{"hash":185343357,"name":"tvpimportpreviewform.caption","sourcebytes":[86,112,73,109,112,111,114,116,80,114,101,118,105,101,119,70,111,114,109],"value":"VpImportPreviewForm"}, +{"hash":4294967295,"name":"tvpimportpreviewform.grid.columns[0].title.caption","sourcebytes":[],"value":""}, +{"hash":5286979,"name":"tvpimportpreviewform.grid.columns[1].title.caption","sourcebytes":[73,116,101,109,115],"value":"Items"}, +{"hash":202226323,"name":"tvpimportpreviewform.btnexecute.caption","sourcebytes":[73,109,112,111,114,116,32,99,104,101,99,107,101,100,32,105,116,101,109,115],"value":"Import checked items"}, +{"hash":77089212,"name":"tvpimportpreviewform.btncancel.caption","sourcebytes":[67,97,110,99,101,108],"value":"Cancel"} +]} diff --git a/components/tvplanit/source/vpimportpreview.pas b/components/tvplanit/source/vpimportpreview.pas new file mode 100644 index 000000000..9b2726b81 --- /dev/null +++ b/components/tvplanit/source/vpimportpreview.pas @@ -0,0 +1,203 @@ +unit VpImportPreview; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Graphics, Types, + Forms, Controls, Dialogs, Grids, ExtCtrls, StdCtrls; + +type + + { TVpImportPreviewForm } + + TVpImportPreviewForm = class(TForm) + btnExecute: TButton; + btnCancel: TButton; + Grid: TDrawGrid; + ButtonPanel: TPanel; + procedure GridDrawCell(Sender: TObject; aCol, aRow: Integer; aRect: TRect; + {%H-}aState: TGridDrawState); + procedure GridGetCheckboxState(Sender: TObject; {%H-}ACol, ARow: Integer; + var Value: TCheckboxState); + procedure GridPrepareCanvas({%H-}sender: TObject; aCol, {%H-}aRow: Integer; + {%H-}aState: TGridDrawState); + procedure GridSetCheckboxState(Sender: TObject; {%H-}ACol, ARow: Integer; + const Value: TCheckboxState); + private + + protected + FItems: TFPList; + procedure CalcRowHeights; + function GetCellText({%H-}ACol, {%H-}ARow: Integer): String; virtual; + procedure PrepareItems; virtual; + + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure CheckItem({%H-}ARow: Integer; {%H-}AChecked: Boolean); virtual; + function Execute: Boolean; + function IsChecked({%H-}ARow: Integer): Boolean; virtual; + + end; + +var + VpImportPreviewForm: TVpImportPreviewForm; + +implementation + +{$R *.lfm} + +uses + LCLIntf, LCLType; + +{ TVpImportPreviewForm } + +constructor TVpImportPreviewForm.Create(AOwner: TComponent); +begin + inherited; + Grid.Options := Grid.Options + [goRowSelect]; + FItems := TFPList.Create; +end; + +destructor TVpImportPreviewForm.Destroy; +begin + FItems.Free; + inherited; +end; + +procedure TVpImportPreviewForm.CalcRowHeights; +var + bmp: TBitmap; + row: Integer; + R: TRect; + flags: Integer; + s: String; +begin + flags := DT_CALCRECT + DT_WORDBREAK; + bmp := TBitmap.Create; + try + bmp.SetSize(1, 1); + bmp.Canvas.Font := Grid.Font; + for row := 1 to Grid.RowCount-1 do + begin + R := Rect(0, 0, MaxInt, 0); + s := GetCellText(1, row); + if s <> '' then + begin + DrawText(bmp.Canvas.Handle, PChar(s), Length(s), R, flags); + Grid.RowHeights[row] := R.Bottom - R.Top + 2*varCellPadding; + end else + Grid.RowHeights[row] := Grid.DefaultRowHeight; + end; + finally + bmp.Free; + end; +end; + +{ Marks the item in the specified row to be accepted for import. + To be overridden by ancestors. } +procedure TVpImportPreviewForm.CheckItem(ARow: Integer; AChecked: Boolean); +begin + // +end; + +function TVpImportPreviewForm.Execute: Boolean; +begin + Result := ShowModal = mrOK; +end; + +{ Returns the text to be displayed in the grid. + To be overridden by ancestors. } +function TVpImportPreviewForm.GetCellText(ACol, ARow: Integer): String; +begin + Result := ''; +end; + +procedure TVpImportPreviewForm.GridDrawCell(Sender: TObject; aCol, + aRow: Integer; aRect: TRect; aState: TGridDrawState); +var + s: String; + R: TRect; +begin + R := ARect; + InflateRect(R, -varCellPadding, - varCellPadding); + s := GetCellText(ACol, ARow); + Grid.Canvas.TextRect(R, R.Left, R.Top, s); +end; + +procedure TVpImportPreviewForm.GridGetCheckboxState(Sender: TObject; ACol, + ARow: Integer; var Value: TCheckboxState); +begin + if ARow >= Grid.FixedRows then + begin + if IsChecked(ARow) then + Value := cbChecked + else + Value := cbUnChecked; + end; +end; + +procedure TVpImportPreviewForm.GridPrepareCanvas(sender: TObject; aCol, + aRow: Integer; aState: TGridDrawState); +var + ts: TTextStyle; +begin + if ACol = 1 then + begin + ts := Grid.Canvas.TextStyle; + ts.SingleLine := false; + ts.Wordbreak := true; + Grid.Canvas.TextStyle := ts; + end; +end; + +procedure TVpImportPreviewForm.GridSetCheckboxState(Sender: TObject; ACol, + ARow: Integer; const Value: TCheckboxState); +begin + if ARow >= Grid.FixedRows then + CheckItem(ARow, Value = cbChecked); +end; + +{ Returns that the item in the given row should be included in the import process. + To be overridden by ancestors. } +function TVpImportPreviewForm.IsChecked(ARow: Integer): Boolean; +begin + Result := false; +end; + +{ Must be overridden to add the items to be imported from the external list to + the internal list FList. + Must call inherited at the end to set the grid's RowCount and row heights. } +procedure TVpImportPreviewForm.PrepareItems; +begin + // populate FList here... + Grid.RowCount := Grid.FixedRows + FItems.Count; + CalcRowHeights; +end; +{ +var + i: Integer; +begin + FItems.Clear; + if FCalendar <> nil then + begin + case FKind of + icEvent: + for i := 0 to FCalendar.Count-1 do + if (FCalendar.Entry[i] is TVpICalEvent) then + FItems.Add(FCalendar.Entry[i]); + icToDo: + for i := 0 to FCalendar.Count-1 do + if (FCalendar.Entry[i] is TVpICalToDo) then + FItems.Add(FCalendar.Entry[i]); + end; + Grid.RowCount := Grid.FixedRows + FItems.Count; + CalcRowHeights; + end else + Grid.RowCount := Grid.FixedRows; +end; +} +end. + diff --git a/components/tvplanit/source/vpimportpreview_icalevent.lfm b/components/tvplanit/source/vpimportpreview_icalevent.lfm new file mode 100644 index 000000000..f99a076ab --- /dev/null +++ b/components/tvplanit/source/vpimportpreview_icalevent.lfm @@ -0,0 +1,41 @@ +inherited VpImportPreviewICalEventForm: TVpImportPreviewICalEventForm + Height = 400 + Width = 667 + Caption = '' + ClientHeight = 400 + ClientWidth = 667 + inherited Grid: TDrawGrid + Height = 363 + Width = 667 + Columns = < + item + Alignment = taCenter + ButtonStyle = cbsCheckboxColumn + PickList.Strings = ( ) + SizePriority = 0 + Title.Caption = '' + Width = 33 + end + item + PickList.Strings = ( ) + ReadOnly = True + Title.Caption = 'Items' + Width = 634 + end> + ColWidths = ( + 33 + 634 + ) + end + inherited ButtonPanel: TPanel + Top = 369 + Width = 655 + ClientWidth = 655 + inherited btnExecute: TButton + Left = 439 + end + inherited btnCancel: TButton + Left = 580 + end + end +end diff --git a/components/tvplanit/source/vpimportpreview_icalevent.lrj b/components/tvplanit/source/vpimportpreview_icalevent.lrj new file mode 100644 index 000000000..bcccfd80f --- /dev/null +++ b/components/tvplanit/source/vpimportpreview_icalevent.lrj @@ -0,0 +1,5 @@ +{"version":1,"strings":[ +{"hash":4294967295,"name":"tvpimportpreviewicaleventform.caption","sourcebytes":[],"value":""}, +{"hash":4294967295,"name":"tvpimportpreviewicaleventform.grid.columns[0].title.caption","sourcebytes":[],"value":""}, +{"hash":5286979,"name":"tvpimportpreviewicaleventform.grid.columns[1].title.caption","sourcebytes":[73,116,101,109,115],"value":"Items"} +]} diff --git a/components/tvplanit/source/vpimportpreview_icalevent.pas b/components/tvplanit/source/vpimportpreview_icalevent.pas new file mode 100644 index 000000000..00410f0f9 --- /dev/null +++ b/components/tvplanit/source/vpimportpreview_icalevent.pas @@ -0,0 +1,207 @@ +unit VpImportPreview_ICalEvent; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, + VpData, VpBaseDS, VpImportPreview, VpICal; + +type + + { TVpImportPreviewICalEventForm } + + TVpImportPreviewICalEventForm = class(TVpImportPreviewForm) + private + FCalendar: TVpICalendar; + FDatastore: TVpCustomDatastore; + FDefaultCategory: String; + FTimeFormat: String; + function GetEventText(AEvent: TVpICalEvent): String; + procedure SetCalendar(const AValue: TVpICalendar); + + protected + function GetCellText(ACol, ARow: Integer): String; override; + procedure PrepareItems; override; + + public + constructor Create(AOwner: TComponent); override; + procedure CheckItem(ARow: Integer; AChecked: Boolean); override; + function IsChecked(ARow: Integer): Boolean; override; + property Calendar: TVpICalendar read FCalendar write SetCalendar; + property Datastore: TVpCustomDatastore read FDatastore write FDatastore; + property DefaultCategory: String read FDefaultCategory write FDefaultCategory; +// property Kind: TVpICalItemKind read FKind write SetKind; + + end; + +var + VpImportPreviewICalEventForm: TVpImportPreviewICalEventForm; + +implementation + +{$R *.lfm} + +uses + VpSR; + +constructor TVPImportPreviewICalEventForm.Create(AOwner: TComponent); +begin + inherited; + Caption := RSImportICalEvent; + FTimeFormat := 'c'; // short date + long time format +end; + +procedure TVpImportPreviewICalEventForm.CheckItem(ARow: Integer; AChecked: Boolean); +var + item: TVpICalEntry; +begin + if ARow < Grid.FixedRows then + exit; + item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); + if item <> nil then + item.Skip := not AChecked; +end; + +function TVpImportPreviewICalEventForm.GetCellText(ACol, ARow: Integer): String; +var + item: TVpICalEntry; +begin + Result := ''; + if (ACol = 1) and (ARow >= Grid.FixedRows) then + begin + item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); + if item <> nil then + Result := GetEventText(TVpICalEvent(item)); + end; +end; + +function TVpImportPreviewICalEventForm.GetEventText(AEvent: TVpICalEvent): String; +var + startTime, endTime: TDateTime; + sStartTime, sEndTime: String; + advTime: Integer; + advTimeUnits: TVpAlarmAdvType; + dingPath: String; + s: String; + cat: String; +begin + startTime := AEvent.StartTime[false]; + endTime := AEvent.EndTime[false]; + sStartTime := FormatDateTime(FTimeFormat, startTime); + sEndTime := FormatDateTime(FTimeFormat, endTime); + if TVpEvent.IsAllDayEvent(startTime, endTime) then + begin + if trunc(startTime) = trunc(endTime) then + Result := Format('%s (%s)', [sStartTime, RSAllDay]) + else + Result := Format('%s - %s (%s)', [sStartTime, sEndTime, RSAllDay]); + end else + Result := + RSStartTimeLbl + ' ' + sStartTime + LineEnding + + RSEndTimeLbl + ' ' + sEndTime; + + Result := Result + LineEnding + + RSDescriptionLbl + ' ' + AEvent.Summary + LineEnding + + RSCategoryLbl + ' '; + + // Categories + if Assigned(FDatastore) then + begin + cat := FDatastore.FindBestEventCategory(AEvent.Categories); + if cat = '' then cat := FDefaultCategory; + Result := Result + cat; + end; + + // Recurrence + if AEvent.RecurrenceFrequency <> '' then + begin + s := ''; + case Uppercase(AEvent.RecurrenceFrequency) of + 'YEARLY': + if AEvent.RecurrenceInterval in [0, 1] then + s := Format(RSYearlyOn, [FormatDateTime('dd/mm',startTime)]) + else + s := Format(RSEveryYearsOn, [AEvent.RecurrenceInterval, FormatDateTime('dd/mm', startTime)]); + 'MONTHLY': + if AEvent.RecurrenceInterval in [0, 1] then + s := Format(RSMonthlyOn, [FormatDateTime('d', startTime)]) + else + s := Format(RSEveryMonthsOn, [AEvent.RecurrenceInterval, FormatDateTime('d', startTime)]); + 'WEEKLY': + if AEvent.RecurrenceInterval in [0, 1] then + s := Format(RSWeeklyOn, [FormatDateTime('dddd',startTime)]) + else + s := Format(RSEveryWeeksOn, [AEvent.RecurrenceInterval, FormatDateTime('ddd', startTime)]); + 'DAILY': + if AEvent.RecurrenceInterval in [0, 1] then + s := RSDaily + else + s := Format(RSEveryDays, [AEvent.RecurrenceInterval]); + end; + if s <> '' then + Result := Result + LineEnding + RSRepeat + ' ' + s; + end; + + // Alarm + if AEvent.Alarm <> nil then + begin + TVpEvent.GetAlarmParams(AEvent.Alarm.Trigger, advTime, advTimeUnits); + dingPath := AEvent.Alarm.AudioSrc; + if advTime <> 1 then + begin + case advTimeUnits of + atMinutes: s := Format(RSXMinutes, [advTime]); + atHours: s := Format(RSXHours, [advTime]); + atDays: s := Format(RSXDays, [advTime]); + end; + s := Format(RSAlarmIn, [s]); + end else + case advTimeUnits of + atMinutes: s := Format(RSAlarmIn, [RS1Minute]); + atHours: s := Format(RSAlarmIn, [RS1Hour]); + atDays: s := Format(RSAlarmIn, [RS1Day]); + end; + Result := Result + LineEnding + s; + if FileExists(dingPath) then + Result := Format('%s, %s: %s', [Result, RSSound, dingPath]); + end else + Result := Result + LineEnding + RSNoAlarm; +end; + +function TVpImportPreviewICalEventForm.IsChecked(ARow: Integer): Boolean; +var + item: TVpICalEntry; +begin + Result := false; + if ARow < Grid.FixedRows then + exit; + item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); + if (item <> nil) then + Result := not item.Skip; +end; + +procedure TVpImportPreviewICalEventForm.PrepareItems; +var + i: Integer; +begin + FItems.Clear; + if FCalendar <> nil then + for i := 0 to FCalendar.Count-1 do + if (FCalendar.Entry[i] is TVpICalEvent) then + FItems.Add(FCalendar.Entry[i]); + inherited; +end; + +procedure TVpImportPreviewICalEventForm.SetCalendar(const AValue: TVpICalendar); +begin + if AValue <> FCalendar then + begin + FCalendar := AValue; + PrepareItems; + end; +end; + +end. + diff --git a/components/tvplanit/source/vpimportpreview_icaltask.lfm b/components/tvplanit/source/vpimportpreview_icaltask.lfm new file mode 100644 index 000000000..8b5509edc --- /dev/null +++ b/components/tvplanit/source/vpimportpreview_icaltask.lfm @@ -0,0 +1,41 @@ +inherited VpImportPreviewICalTaskForm: TVpImportPreviewICalTaskForm + Height = 400 + Width = 667 + Caption = '' + ClientHeight = 400 + ClientWidth = 667 + inherited Grid: TDrawGrid + Height = 363 + Width = 667 + Columns = < + item + Alignment = taCenter + ButtonStyle = cbsCheckboxColumn + PickList.Strings = ( ) + SizePriority = 0 + Title.Caption = '' + Width = 33 + end + item + PickList.Strings = ( ) + ReadOnly = True + Title.Caption = 'Items' + Width = 630 + end> + ColWidths = ( + 33 + 630 + ) + end + inherited ButtonPanel: TPanel + Top = 369 + Width = 655 + ClientWidth = 655 + inherited btnExecute: TButton + Left = 439 + end + inherited btnCancel: TButton + Left = 580 + end + end +end diff --git a/components/tvplanit/source/vpimportpreview_icaltask.lrj b/components/tvplanit/source/vpimportpreview_icaltask.lrj new file mode 100644 index 000000000..1e6f793fb --- /dev/null +++ b/components/tvplanit/source/vpimportpreview_icaltask.lrj @@ -0,0 +1,5 @@ +{"version":1,"strings":[ +{"hash":4294967295,"name":"tvpimportpreviewicaltaskform.caption","sourcebytes":[],"value":""}, +{"hash":4294967295,"name":"tvpimportpreviewicaltaskform.grid.columns[0].title.caption","sourcebytes":[],"value":""}, +{"hash":5286979,"name":"tvpimportpreviewicaltaskform.grid.columns[1].title.caption","sourcebytes":[73,116,101,109,115],"value":"Items"} +]} diff --git a/components/tvplanit/source/vpimportpreview_icaltask.pas b/components/tvplanit/source/vpimportpreview_icaltask.pas new file mode 100644 index 000000000..c125601a7 --- /dev/null +++ b/components/tvplanit/source/vpimportpreview_icaltask.pas @@ -0,0 +1,138 @@ +unit VpImportPreview_ICalTask; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, + VpData, VpBaseDS, VpImportPreview, VpICal; + +type + + { TVpImportPreviewICalTaskForm } + + TVpImportPreviewICalTaskForm = class(TVpImportPreviewForm) + private + FCalendar: TVpICalendar; + FDatastore: TVpCustomDatastore; + FDefaultCategory: String; + FTimeFormat: String; + function GetTaskText(AToDo: TVpICalToDo): String; + procedure SetCalendar(const AValue: TVpICalendar); + + protected + function GetCellText(ACol, ARow: Integer): String; override; + procedure PrepareItems; override; + + public + constructor Create(AOwner: TComponent); override; + procedure CheckItem(ARow: Integer; AChecked: Boolean); override; + function IsChecked(ARow: Integer): Boolean; override; + property Calendar: TVpICalendar read FCalendar write SetCalendar; + property Datastore: TVpCustomDatastore read FDatastore write FDatastore; + property DefaultCategory: String read FDefaultCategory write FDefaultCategory; +// property Kind: TVpICalItemKind read FKind write SetKind; + + end; + +var + VpImportPreviewICalTaskForm: TVpImportPreviewICalTaskForm; + +implementation + +{$R *.lfm} + +uses + VpSR; + +constructor TVPImportPreviewICalTaskForm.Create(AOwner: TComponent); +begin + inherited; + Caption := RSImportICalTask; + FTimeFormat := 'c'; // short date + long time format +end; + +procedure TVpImportPreviewICalTaskForm.CheckItem(ARow: Integer; AChecked: Boolean); +var + item: TVpICalEntry; +begin + if ARow < Grid.FixedRows then + exit; + item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); + if item <> nil then + item.Skip := not AChecked; +end; + +function TVpImportPreviewICalTaskForm.GetCellText(ACol, ARow: Integer): String; +var + item: TVpICalEntry; +begin + Result := ''; + if (ACol = 1) and (ARow >= Grid.FixedRows) then + begin + item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); + if item <> nil then + Result := GetTaskText(TVpICalToDo(item)); + end; +end; + +function TVpImportPreviewICalTaskForm.GetTaskText(AToDo: TVpICalToDo): String; +var + s: String; + cat: String; +begin + Result := RSDescriptionLbl + ' ' + AToDo.Summary + LineEnding + + RSDueDateLabel + ' ' + FormatDateTime(FTimeFormat, AToDo.DueTime[false]) + LineEnding + + RSCreatedOn + ' ' + FormatDateTime(FTimeFormat, AToDo.StartTime[false]); + + case TVpTask.GetTaskPriority(AToDo.Priority) of + tpLow: s := RSLow; + tpNormal: s := RSNormal; + tpHigh: s := RSHigh; + end; + Result := Result + LineEnding + RSPriorityLabel + ' ' + s + LineEnding + RSCategoryLabel + ' '; + + if Assigned(FDatastore) then + begin + cat := FDatastore.FindBestTaskCategory(AToDo.Categories); + if cat = '' then cat := FDefaultCategory; + Result := Result + cat; + end; +end; + +function TVpImportPreviewICalTaskForm.IsChecked(ARow: Integer): Boolean; +var + item: TVpICalEntry; +begin + Result := false; + if ARow < Grid.FixedRows then + exit; + item := TVpICalEntry(FItems[ARow - Grid.FixedRows]); + if (item <> nil) then + Result := not item.Skip; +end; + +procedure TVpImportPreviewICalTaskForm.PrepareItems; +var + i: Integer; +begin + FItems.Clear; + if FCalendar <> nil then + for i := 0 to FCalendar.Count-1 do + if (FCalendar.Entry[i] is TVpICalToDo) then + FItems.Add(FCalendar.Entry[i]); + inherited; +end; + +procedure TVpImportPreviewICalTaskForm.SetCalendar(const AValue: TVpICalendar); +begin + if AValue <> FCalendar then + begin + FCalendar := AValue; + PrepareItems; + end; +end; + +end. + diff --git a/components/tvplanit/source/vptasklist.pas b/components/tvplanit/source/vptasklist.pas index fcf6490c3..c620de1bf 100644 --- a/components/tvplanit/source/vptasklist.pas +++ b/components/tvplanit/source/vptasklist.pas @@ -264,7 +264,7 @@ implementation uses SysUtils, Forms, Dialogs, - VpDlg, VpTaskEditDlg, VpTasklistPainter, VpICal; + VpDlg, VpTaskEditDlg, VpTasklistPainter; (*****************************************************************************)