You've already forked lazarus-ccr
tvplanit: Import tasks from VTODO section of iCalendar files (*.ics, *.ical)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6502 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -929,6 +929,12 @@ msgid "Add event..."
|
|||||||
msgstr "Ereignis hinzufügen..."
|
msgstr "Ereignis hinzufügen..."
|
||||||
|
|
||||||
#: vpsr.rspopupaddeventfromical
|
#: vpsr.rspopupaddeventfromical
|
||||||
|
msgctxt "vpsr.rspopupaddeventfromical"
|
||||||
|
msgid "Import from iCalendar file(s)..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: vpsr.rspopupaddtaskfromical
|
||||||
|
msgctxt "vpsr.rspopupaddtaskfromical"
|
||||||
msgid "Import from iCalendar file(s)..."
|
msgid "Import from iCalendar file(s)..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -920,6 +920,12 @@ msgid "Add event..."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: vpsr.rspopupaddeventfromical
|
#: vpsr.rspopupaddeventfromical
|
||||||
|
msgctxt "vpsr.rspopupaddeventfromical"
|
||||||
|
msgid "Import from iCalendar file(s)..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: vpsr.rspopupaddtaskfromical
|
||||||
|
msgctxt "vpsr.rspopupaddtaskfromical"
|
||||||
msgid "Import from iCalendar file(s)..."
|
msgid "Import from iCalendar file(s)..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -935,6 +935,12 @@ msgid "Add event..."
|
|||||||
msgstr "Ajouter un événement..."
|
msgstr "Ajouter un événement..."
|
||||||
|
|
||||||
#: vpsr.rspopupaddeventfromical
|
#: vpsr.rspopupaddeventfromical
|
||||||
|
msgctxt "vpsr.rspopupaddeventfromical"
|
||||||
|
msgid "Import from iCalendar file(s)..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: vpsr.rspopupaddtaskfromical
|
||||||
|
msgctxt "vpsr.rspopupaddtaskfromical"
|
||||||
msgid "Import from iCalendar file(s)..."
|
msgid "Import from iCalendar file(s)..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -929,6 +929,12 @@ msgid "Add event..."
|
|||||||
msgstr "Gebeurtenis toevoegen..."
|
msgstr "Gebeurtenis toevoegen..."
|
||||||
|
|
||||||
#: vpsr.rspopupaddeventfromical
|
#: vpsr.rspopupaddeventfromical
|
||||||
|
msgctxt "vpsr.rspopupaddeventfromical"
|
||||||
|
msgid "Import from iCalendar file(s)..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: vpsr.rspopupaddtaskfromical
|
||||||
|
msgctxt "vpsr.rspopupaddtaskfromical"
|
||||||
msgid "Import from iCalendar file(s)..."
|
msgid "Import from iCalendar file(s)..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -919,6 +919,12 @@ msgid "Add event..."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: vpsr.rspopupaddeventfromical
|
#: vpsr.rspopupaddeventfromical
|
||||||
|
msgctxt "vpsr.rspopupaddeventfromical"
|
||||||
|
msgid "Import from iCalendar file(s)..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: vpsr.rspopupaddtaskfromical
|
||||||
|
msgctxt "vpsr.rspopupaddtaskfromical"
|
||||||
msgid "Import from iCalendar file(s)..."
|
msgid "Import from iCalendar file(s)..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -929,6 +929,12 @@ msgid "Add event..."
|
|||||||
msgstr "Добавить событие..."
|
msgstr "Добавить событие..."
|
||||||
|
|
||||||
#: vpsr.rspopupaddeventfromical
|
#: vpsr.rspopupaddeventfromical
|
||||||
|
msgctxt "vpsr.rspopupaddeventfromical"
|
||||||
|
msgid "Import from iCalendar file(s)..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: vpsr.rspopupaddtaskfromical
|
||||||
|
msgctxt "vpsr.rspopupaddtaskfromical"
|
||||||
msgid "Import from iCalendar file(s)..."
|
msgid "Import from iCalendar file(s)..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -185,6 +185,7 @@ resourcestring
|
|||||||
{Task Specific}
|
{Task Specific}
|
||||||
RSConfirmDeleteTask = 'Delete this task from your list?';
|
RSConfirmDeleteTask = 'Delete this task from your list?';
|
||||||
RSTaskPopupAdd = 'Add task...';
|
RSTaskPopupAdd = 'Add task...';
|
||||||
|
RSPopupAddTaskFromICal = 'Import from iCalendar file(s)...';
|
||||||
RSTaskPopupEdit = 'Edit task...';
|
RSTaskPopupEdit = 'Edit task...';
|
||||||
RSTaskPopupDelete = 'Delete task...';
|
RSTaskPopupDelete = 'Delete task...';
|
||||||
RSTaskTitleResource = 'Task list - '; {!!.01}
|
RSTaskTitleResource = 'Task list - '; {!!.01}
|
||||||
|
@ -422,6 +422,7 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create(Owner: TVpTasks);
|
constructor Create(Owner: TVpTasks);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
procedure LoadFromICalendar(AEntry: TVpICalToDo);
|
||||||
property Loading: Boolean read FLoading write FLoading;
|
property Loading: Boolean read FLoading write FLoading;
|
||||||
property Changed: Boolean read FChanged write SetChanged;
|
property Changed: Boolean read FChanged write SetChanged;
|
||||||
property Deleted: Boolean read FDeleted write FDeleted;
|
property Deleted: Boolean read FDeleted write FDeleted;
|
||||||
@ -439,8 +440,8 @@ type
|
|||||||
property Complete: Boolean read FComplete write SetComplete;
|
property Complete: Boolean read FComplete write SetComplete;
|
||||||
property CreatedOn: TDateTime read FCreatedOn write SetCreatedOn;
|
property CreatedOn: TDateTime read FCreatedOn write SetCreatedOn;
|
||||||
property CompletedOn: TDateTIme read FCompletedOn write SetCompletedOn;
|
property CompletedOn: TDateTIme read FCompletedOn write SetCompletedOn;
|
||||||
property Priority: Integer read FPriority write SetPriority;
|
property Priority: Integer read FPriority write SetPriority; // --> TVpTaskPriority
|
||||||
property Category: Integer read FCategory write SetCategory;
|
property Category: Integer read FCategory write SetCategory; // --> TVpCategoryType
|
||||||
|
|
||||||
{ Reserved for your use }
|
{ Reserved for your use }
|
||||||
property UserField0: string read FUserField0 write FUserField0;
|
property UserField0: string read FUserField0 write FUserField0;
|
||||||
@ -1305,7 +1306,6 @@ begin
|
|||||||
FCategory := k;
|
FCategory := k;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ All-day event }
|
{ All-day event }
|
||||||
FAllDayEvent := (frac(FStartTime) = 0) and (frac(FEndTime) = 0);
|
FAllDayEvent := (frac(FStartTime) = 0) and (frac(FEndTime) = 0);
|
||||||
|
|
||||||
@ -1361,18 +1361,6 @@ begin
|
|||||||
FRepeatCode := rtCustom;
|
FRepeatCode := rtCustom;
|
||||||
FCustInterval := AEntry.RecurrenceInterval; // * SecondsInDay;
|
FCustInterval := AEntry.RecurrenceInterval; // * SecondsInDay;
|
||||||
end;
|
end;
|
||||||
(*
|
|
||||||
'HOURLY':
|
|
||||||
begin
|
|
||||||
FRepeatCode := rtCustom;
|
|
||||||
FCustInterval := AEntry.RecurrenceInterval * SecondsInHour;
|
|
||||||
end;
|
|
||||||
'MINUTELY':
|
|
||||||
begin
|
|
||||||
FRepeatCode := rtCustom;
|
|
||||||
FCustInterval := AEntry.RecurrenceInterval * SecondsInMinute;
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
end;
|
end;
|
||||||
if (AEntry.RecurrenceEndDate = 0) and (AEntry.RecurrenceCount > 0) then begin
|
if (AEntry.RecurrenceEndDate = 0) and (AEntry.RecurrenceCount > 0) then begin
|
||||||
FRepeatRangeEnd := trunc(FStartTime);
|
FRepeatRangeEnd := trunc(FStartTime);
|
||||||
@ -1388,9 +1376,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
FRepeatRangeEnd := AEntry.RecurrenceEndDate;
|
FRepeatRangeEnd := AEntry.RecurrenceEndDate;
|
||||||
|
|
||||||
// There is also "CustomInterval" which may be extracted from the RecurrenceByXXXX data
|
|
||||||
// But this is very complex...
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TVpEvent.SetAlarmAdv(Value: Integer);
|
procedure TVpEvent.SetAlarmAdv(Value: Integer);
|
||||||
@ -2674,6 +2659,55 @@ begin
|
|||||||
result := (Trunc(DueDate) < now + 1);
|
result := (Trunc(DueDate) < now + 1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TVpTask.LoadFromICalendar(AEntry: TVpICalToDo);
|
||||||
|
var
|
||||||
|
dt: Double;
|
||||||
|
cat: String;
|
||||||
|
i, j, k: Integer;
|
||||||
|
ct: TVpCategoryType;
|
||||||
|
catFound: Boolean;
|
||||||
|
begin
|
||||||
|
if AEntry = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{ Standard event properties }
|
||||||
|
FDescription := AEntry.Summary;
|
||||||
|
FDetails := AEntry.Comment;
|
||||||
|
FCreatedOn := AEntry.StartTime[false];
|
||||||
|
FDueDate := AEntry.DueTime[false];
|
||||||
|
FCompletedOn := AEntry.CompletedTime[false];
|
||||||
|
|
||||||
|
{ Status }
|
||||||
|
FComplete := SameText(AEntry.Status, 'COMPLETED');
|
||||||
|
|
||||||
|
{ Priority }
|
||||||
|
case AEntry.Priority of
|
||||||
|
1, 2, 3: FPriority := ord(tpHigh);
|
||||||
|
4, 5, 6: FPriority := ord(tpNormal);
|
||||||
|
7, 8, 9: FPriority := ord(tpLow);
|
||||||
|
else FPriority := ord(tpNormal);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Category }
|
||||||
|
{ tvplanit has only 1 category, ical may have several. We pick the first one
|
||||||
|
defined by TVpCategorytype. If none is found we select ctOther. }
|
||||||
|
FCategory := ord(ctOther);
|
||||||
|
catFound := false;
|
||||||
|
if AEntry.CategoryCount > 0 then begin
|
||||||
|
for i := 0 to AEntry.CategoryCount-1 do begin
|
||||||
|
cat := AEntry.category[i];
|
||||||
|
for ct in TVpCategoryType do begin
|
||||||
|
if cat = CategoryLabel(ct) then begin
|
||||||
|
FCategory := ord(ct);
|
||||||
|
catFound := true;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if catFound then break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TVpTask.SetCategory(const Value: Integer);
|
procedure TVpTask.SetCategory(const Value: Integer);
|
||||||
begin
|
begin
|
||||||
if Value <> FCategory then begin
|
if Value <> FCategory then begin
|
||||||
|
@ -89,6 +89,40 @@ type
|
|||||||
property RecurrenceByXXX: String read FRecurrenceByXXX;
|
property RecurrenceByXXX: String read FRecurrenceByXXX;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TVpICalToDo = class(TVpICalEntry)
|
||||||
|
private
|
||||||
|
FSummary: String;
|
||||||
|
FComment: String;
|
||||||
|
FStartTime: TDateTime;
|
||||||
|
FStartTimeTZ: String;
|
||||||
|
FDueTime: TDateTime;
|
||||||
|
FDueTimeTZ: String;
|
||||||
|
FCompletedTime: TDateTime;
|
||||||
|
FCompletedTimeTZ: String;
|
||||||
|
FDuration: double;
|
||||||
|
FCategories: TStrings;
|
||||||
|
FPriority: integer;
|
||||||
|
FStatus: String;
|
||||||
|
function GetCategory(AIndex: integer): String;
|
||||||
|
function GetCategoryCount: Integer;
|
||||||
|
function GetCompletedTime(UTC: Boolean): TDateTime;
|
||||||
|
function GetDueTime(UTC: Boolean): TDateTime;
|
||||||
|
function GetStartTime(UTC: Boolean): TDateTime;
|
||||||
|
public
|
||||||
|
constructor Create(AOwner: TVpICalendar); override;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Analyze; override;
|
||||||
|
property Summary: String read FSummary;
|
||||||
|
property Comment: String read FComment;
|
||||||
|
property StartTime[UTC: Boolean]: TDateTime read GetStartTime;
|
||||||
|
property DueTime[UTC: Boolean]: TDateTime read GetDueTime;
|
||||||
|
property CompletedTime[UTC: Boolean]: TDateTime read GetCompletedTime;
|
||||||
|
property Category[AIndex: Integer]: String read GetCategory;
|
||||||
|
property CategoryCount: Integer read GetCategoryCount;
|
||||||
|
property Priority: Integer read FPriority; // 0=undefined, 1-highest, 9=lowest
|
||||||
|
property Status: String read FStatus;
|
||||||
|
end;
|
||||||
|
|
||||||
TVpICalendar = class
|
TVpICalendar = class
|
||||||
private
|
private
|
||||||
FEntries: array of TVpICalEntry;
|
FEntries: array of TVpICalEntry;
|
||||||
@ -411,6 +445,114 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{==============================================================================}
|
||||||
|
{ TVpICalToDo }
|
||||||
|
{==============================================================================}
|
||||||
|
|
||||||
|
constructor TVpICalToDo.Create(AOwner: TVpICalendar);
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
FCategories := TStringList.Create;
|
||||||
|
FCategories.Delimiter := VALUE_DELIMITER;
|
||||||
|
FCategories.StrictDelimiter := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TVpICalToDo.Destroy;
|
||||||
|
begin
|
||||||
|
FCategories.Free;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TVpICalToDo.Analyze;
|
||||||
|
var
|
||||||
|
i, j: Integer;
|
||||||
|
item: TVpICalItem;
|
||||||
|
L: TStrings;
|
||||||
|
s: String;
|
||||||
|
isUTC: Boolean;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
|
||||||
|
for i := 0 to FItems.Count-1 do begin
|
||||||
|
item := TVpICalItem(FItems[i]);
|
||||||
|
case item.Key of
|
||||||
|
'SUMMARY':
|
||||||
|
FSummary := item.Value;
|
||||||
|
'COMMENT':
|
||||||
|
FComment := item.Value;
|
||||||
|
'DTSTART':
|
||||||
|
begin
|
||||||
|
FStartTimeTZ := item.GetAttribute('TZID');
|
||||||
|
FStartTime := iCalDateTime(item.Value, isUTC);
|
||||||
|
if not isUTC then
|
||||||
|
FStartTime := FCalendar.LocalTimeToUTC(FStartTime, FStartTimeTZ);
|
||||||
|
end;
|
||||||
|
'DUE':
|
||||||
|
begin
|
||||||
|
FDueTimeTZ := item.GetAttribute('TZID');
|
||||||
|
FDueTime := iCalDateTime(item.Value, isUTC);
|
||||||
|
if not isUTC then
|
||||||
|
FDueTime := FCalendar.LocalTimeToUTC(FDueTime, FDueTimeTZ);
|
||||||
|
end;
|
||||||
|
'DURATION':
|
||||||
|
FDuration := ICalDuration(item.Value);
|
||||||
|
'COMPLETED':
|
||||||
|
begin
|
||||||
|
FCompletedTimeTZ := item.GetAttribute('TZID');
|
||||||
|
FCompletedTime := iCalDateTime(item.Value, isUTC);
|
||||||
|
if not isUTC then
|
||||||
|
FCompletedTime := FCalendar.LocalTimeToUTC(FCompletedTime, FCompletedTimeTZ);
|
||||||
|
end;
|
||||||
|
'CATEGORIES':
|
||||||
|
FCategories.DelimitedText := item.Value;
|
||||||
|
'PRIORITY':
|
||||||
|
FPriority := StrToIntDef(item.Value, 0);
|
||||||
|
'STATUS':
|
||||||
|
FStatus := item.Value;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TVpICalToDo.GetCategory(AIndex: Integer): String;
|
||||||
|
begin
|
||||||
|
if (AIndex >= 0) and (AIndex < FCategories.Count) then
|
||||||
|
Result := FCategories[AIndex]
|
||||||
|
else
|
||||||
|
Result := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TVpICalToDo.GetCategoryCount: Integer;
|
||||||
|
begin
|
||||||
|
Result := FCategories.Count;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TVpICalToDo.GetCompletedTime(UTC: Boolean): TDateTime;
|
||||||
|
begin
|
||||||
|
Result := FCompletedTime;
|
||||||
|
if (Result > 0) and (not UTC) then
|
||||||
|
Result := FCalendar.UTCToLocalTime(Result, FCompletedTimeTZ);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TVpICalToDo.GetDueTime(UTC: Boolean): TDateTime;
|
||||||
|
begin
|
||||||
|
if FDueTime <> 0 then
|
||||||
|
Result := FDueTime
|
||||||
|
else
|
||||||
|
Result := FStartTime + FDuration;
|
||||||
|
if (Result > 0) and (not UTC) then
|
||||||
|
Result := FCalendar.UTCToLocalTime(Result, FDueTimeTZ);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TVpICalToDo.GetStartTime(UTC: Boolean): TDateTime;
|
||||||
|
begin
|
||||||
|
if UTC then
|
||||||
|
Result := FStartTime
|
||||||
|
else
|
||||||
|
Result := FCalendar.LocalTimeToUTC(FStartTime, FStartTimeTZ);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{==============================================================================}
|
{==============================================================================}
|
||||||
{ TVpICalendar }
|
{ TVpICalendar }
|
||||||
{==============================================================================}
|
{==============================================================================}
|
||||||
@ -512,12 +654,15 @@ begin
|
|||||||
currEntry := TVpICalEvent.Create(self);
|
currEntry := TVpICalEvent.Create(self);
|
||||||
FEntries[n] := currEntry;
|
FEntries[n] := currEntry;
|
||||||
end;
|
end;
|
||||||
'VFREEBUSY':
|
|
||||||
currEntry := nil;
|
|
||||||
'VTODO':
|
'VTODO':
|
||||||
currEntry := nil;
|
begin
|
||||||
|
currEntry :=TVpICalToDo.Create(self);
|
||||||
|
FEntries[n] := currEntry;
|
||||||
|
end;
|
||||||
'VJOURNAL':
|
'VJOURNAL':
|
||||||
currEntry := nil;
|
currEntry := nil;
|
||||||
|
'VFREEBUSY':
|
||||||
|
currEntry := nil;
|
||||||
'VALARM':
|
'VALARM':
|
||||||
if currEntry is TVpICalEvent then begin
|
if currEntry is TVpICalEvent then begin
|
||||||
oldEntry := currEntry;
|
oldEntry := currEntry;
|
||||||
|
@ -172,6 +172,7 @@ type
|
|||||||
{ internal methods }
|
{ internal methods }
|
||||||
procedure InitializeDefaultPopup;
|
procedure InitializeDefaultPopup;
|
||||||
procedure PopupAddTask(Sender: TObject);
|
procedure PopupAddTask(Sender: TObject);
|
||||||
|
procedure PopupAddFromICalFile(Sender: TObject);
|
||||||
procedure PopupDeleteTask(Sender: TObject);
|
procedure PopupDeleteTask(Sender: TObject);
|
||||||
procedure PopupEditTask(Sender: TObject);
|
procedure PopupEditTask(Sender: TObject);
|
||||||
procedure tlSetVScrollPos;
|
procedure tlSetVScrollPos;
|
||||||
@ -259,7 +260,8 @@ type
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, Forms, Dialogs, VpTaskEditDlg, VpDlg, VpTasklistPainter;
|
SysUtils, Forms, Dialogs,
|
||||||
|
VpDlg, VpTaskEditDlg, VpTasklistPainter, VpICal;
|
||||||
|
|
||||||
(*****************************************************************************)
|
(*****************************************************************************)
|
||||||
|
|
||||||
@ -848,7 +850,7 @@ procedure TVpTaskList.InitializeDefaultPopup;
|
|||||||
var
|
var
|
||||||
NewItem: TMenuItem;
|
NewItem: TMenuItem;
|
||||||
begin
|
begin
|
||||||
if RSTaskPopupAdd <> '' then begin
|
if RSTaskPopupAdd <> '' then begin // "Add"
|
||||||
NewItem := TMenuItem.Create(Self);
|
NewItem := TMenuItem.Create(Self);
|
||||||
NewItem.Caption := RSTaskPopupAdd;
|
NewItem.Caption := RSTaskPopupAdd;
|
||||||
NewItem.OnClick := PopupAddTask;
|
NewItem.OnClick := PopupAddTask;
|
||||||
@ -856,7 +858,15 @@ begin
|
|||||||
FDefaultPopup.Items.Add(NewItem);
|
FDefaultPopup.Items.Add(NewItem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if RSTaskPopupEdit <> '' then begin
|
if RSPopupAddTaskFromICal <> '' then begin // Import from iCal
|
||||||
|
NewItem := TMenuItem.Create(Self);
|
||||||
|
NewItem.Caption := RSPopupAddTaskFromICal;
|
||||||
|
NewItem.OnClick := PopupAddFromICalFile;
|
||||||
|
NewItem.Tag := 0;
|
||||||
|
FDefaultPopup.Items.Add(NewItem);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if RSTaskPopupEdit <> '' then begin // "Edit"
|
||||||
NewItem := TMenuItem.Create(Self);
|
NewItem := TMenuItem.Create(Self);
|
||||||
NewItem.Caption := RSTaskPopupEdit;
|
NewItem.Caption := RSTaskPopupEdit;
|
||||||
NewItem.OnClick := PopupEditTask;
|
NewItem.OnClick := PopupEditTask;
|
||||||
@ -864,7 +874,7 @@ begin
|
|||||||
FDefaultPopup.Items.Add(NewItem);
|
FDefaultPopup.Items.Add(NewItem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if RSTaskPopupDelete <> '' then begin
|
if RSTaskPopupDelete <> '' then begin // "Delete"
|
||||||
NewItem := TMenuItem.Create(Self);
|
NewItem := TMenuItem.Create(Self);
|
||||||
NewItem.Caption := RSTaskPopupDelete;
|
NewItem.Caption := RSTaskPopupDelete;
|
||||||
NewItem.OnClick := PopupDeleteTask;
|
NewItem.OnClick := PopupDeleteTask;
|
||||||
@ -886,6 +896,51 @@ begin
|
|||||||
end;
|
end;
|
||||||
{=====}
|
{=====}
|
||||||
|
|
||||||
|
procedure TVpTaskList.PopupAddFromICalFile(Sender: TObject);
|
||||||
|
var
|
||||||
|
dlg: TOpenDialog;
|
||||||
|
ical: TVpICalendar;
|
||||||
|
fn: String;
|
||||||
|
i: Integer;
|
||||||
|
id: Integer;
|
||||||
|
begin
|
||||||
|
if ReadOnly or (not CheckCreateResource) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
dlg := TOpenDialog.Create(nil);
|
||||||
|
try
|
||||||
|
dlg.Title := RSLoadICalTitle;
|
||||||
|
dlg.Filter := RSICalFilter;
|
||||||
|
dlg.FileName := '';
|
||||||
|
dlg.Options := dlg.Options + [ofAllowMultiSelect, ofFileMustExist];
|
||||||
|
if dlg.Execute then begin
|
||||||
|
Screen.Cursor := crHourGlass;
|
||||||
|
Application.ProcessMessages;
|
||||||
|
ical := TVpICalendar.Create;
|
||||||
|
try
|
||||||
|
for fn in dlg.Files do begin
|
||||||
|
ical.LoadFromFile(fn);
|
||||||
|
for i := 0 to ical.Count-1 do begin
|
||||||
|
if not (ical[i] is TVpICalToDo) then
|
||||||
|
Continue;
|
||||||
|
id := DataStore.GetNextID(EventsTableName);
|
||||||
|
FActiveTask := Datastore.Resource.Tasks.AddTask(id);
|
||||||
|
FActiveTask.LoadFromICalendar(TVpICalToDo(ical[i]));
|
||||||
|
Datastore.PostTasks;
|
||||||
|
Datastore.NotifyDependents;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Invalidate;
|
||||||
|
finally
|
||||||
|
ical.Free;
|
||||||
|
Screen.Cursor := crDefault;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
dlg.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TVpTaskList.PopupDeleteTask(Sender: TObject);
|
procedure TVpTaskList.PopupDeleteTask(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if ReadOnly then
|
if ReadOnly then
|
||||||
|
Reference in New Issue
Block a user