tvplanit: Export tasks to ical files (needs more testing).

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8404 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2022-08-20 21:21:14 +00:00
parent 774c1feda3
commit c4a2f61db6
16 changed files with 290 additions and 127 deletions

View File

@ -1023,11 +1023,6 @@ msgctxt "vpsr.rspopupaddevent"
msgid "Add event..."
msgstr "Ereignis hinzufügen..."
#: vpsr.rspopupaddtaskfromical
msgctxt "vpsr.rspopupaddtaskfromical"
msgid "Import from iCalendar file(s)..."
msgstr "Von iCalendar-Dateien importieren..."
#: vpsr.rspopupchangedate
msgctxt "vpsr.rspopupchangedate"
msgid "Change date"
@ -1043,13 +1038,13 @@ msgctxt "vpsr.rspopupeditevent"
msgid "Edit event..."
msgstr "Ereignis bearbeiten..."
#: vpsr.rspopupexporteventtoical
#: vpsr.rspopupexporttoical
msgctxt "vpsr.rspopupexporttoical"
msgid "Export to iCalendar file..."
msgstr ""
msgstr "Als iCalendar-Datei exportieren..."
#: vpsr.rspopupimporteventfromical
#, fuzzy
msgctxt "vpsr.rspopupimporteventfromical"
#: vpsr.rspopupimportfromical
msgctxt "vpsr.rspopupimportfromical"
msgid "Import from iCalendar file(s)..."
msgstr "Von iCalendar-Datei(en) importieren..."
@ -1213,7 +1208,7 @@ msgstr "Format speichern als \"%s\"?"
#: vpsr.rssaveicaltitle
msgid "Export to iCal file"
msgstr ""
msgstr "Als iCal-Datei exportieren"
#: vpsr.rssavevcardtitle
msgid "Export to vCard"
@ -1807,4 +1802,3 @@ 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"

View File

@ -1014,11 +1014,6 @@ msgstr "Pixels"
msgid "Add event..."
msgstr "Add event..."
#: vpsr.rspopupaddtaskfromical
msgctxt "vpsr.rspopupaddtaskfromical"
msgid "Import from iCalendar file(s)..."
msgstr "Import from iCalendar file(s)..."
#: vpsr.rspopupchangedate
msgid "Change date"
msgstr "Change date"
@ -1031,13 +1026,13 @@ msgstr "&Delete event..."
msgid "Edit event..."
msgstr "Edit event..."
#: vpsr.rspopupexporteventtoical
#: vpsr.rspopupexporttoical
msgctxt "vpsr.rspopupexporttoical"
msgid "Export to iCalendar file..."
msgstr ""
msgstr "Export to iCalendar file..."
#: vpsr.rspopupimporteventfromical
#, fuzzy
msgctxt "vpsr.rspopupimporteventfromical"
#: vpsr.rspopupimportfromical
msgctxt "vpsr.rspopupimportfromical"
msgid "Import from iCalendar file(s)..."
msgstr "Import from iCalendar file(s)..."
@ -1199,7 +1194,7 @@ msgstr "Save format to \"%s\"?"
#: vpsr.rssaveicaltitle
msgid "Export to iCal file"
msgstr ""
msgstr "Export to iCal file"
#: vpsr.rssavevcardtitle
msgid "Export to vCard"
@ -1788,4 +1783,3 @@ 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"

View File

@ -1014,11 +1014,6 @@ msgctxt "vpsr.rspopupaddevent"
msgid "Add event..."
msgstr ""
#: vpsr.rspopupaddtaskfromical
msgctxt "vpsr.rspopupaddtaskfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""
#: vpsr.rspopupchangedate
msgctxt "vpsr.rspopupchangedate"
msgid "Change date"
@ -1034,12 +1029,13 @@ msgctxt "vpsr.rspopupeditevent"
msgid "Edit event..."
msgstr ""
#: vpsr.rspopupexporteventtoical
#: vpsr.rspopupexporttoical
msgctxt "vpsr.rspopupexporttoical"
msgid "Export to iCalendar file..."
msgstr ""
#: vpsr.rspopupimporteventfromical
msgctxt "vpsr.rspopupimporteventfromical"
#: vpsr.rspopupimportfromical
msgctxt "vpsr.rspopupimportfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""

View File

@ -1029,11 +1029,6 @@ msgctxt "vpsr.rspopupaddevent"
msgid "Add event..."
msgstr "Ajouter un événement..."
#: vpsr.rspopupaddtaskfromical
msgctxt "vpsr.rspopupaddtaskfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""
#: vpsr.rspopupchangedate
msgctxt "vpsr.rspopupchangedate"
msgid "Change date"
@ -1049,12 +1044,13 @@ msgctxt "vpsr.rspopupeditevent"
msgid "Edit event..."
msgstr "Modifier un événement"
#: vpsr.rspopupexporteventtoical
#: vpsr.rspopupexporttoical
msgctxt "vpsr.rspopupexporttoical"
msgid "Export to iCalendar file..."
msgstr ""
#: vpsr.rspopupimporteventfromical
msgctxt "vpsr.rspopupimporteventfromical"
#: vpsr.rspopupimportfromical
msgctxt "vpsr.rspopupimportfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""

View File

@ -1023,11 +1023,6 @@ msgctxt "vpsr.rspopupaddevent"
msgid "Add event..."
msgstr "Gebeurtenis toevoegen..."
#: vpsr.rspopupaddtaskfromical
msgctxt "vpsr.rspopupaddtaskfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""
#: vpsr.rspopupchangedate
msgctxt "vpsr.rspopupchangedate"
msgid "Change date"
@ -1043,12 +1038,13 @@ msgctxt "vpsr.rspopupeditevent"
msgid "Edit event..."
msgstr "Gebeurtenis bewerken..."
#: vpsr.rspopupexporteventtoical
#: vpsr.rspopupexporttoical
msgctxt "vpsr.rspopupexporttoical"
msgid "Export to iCalendar file..."
msgstr ""
#: vpsr.rspopupimporteventfromical
msgctxt "vpsr.rspopupimporteventfromical"
#: vpsr.rspopupimportfromical
msgctxt "vpsr.rspopupimportfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""

View File

@ -1022,11 +1022,6 @@ msgstr "Pixele"
msgid "Add event..."
msgstr "Dodaj wydarzenie..."
#: vpsr.rspopupaddtaskfromical
msgctxt "vpsr.rspopupaddtaskfromical"
msgid "Import from iCalendar file(s)..."
msgstr "Import z pliku iCalendar..."
#: vpsr.rspopupchangedate
msgctxt "vpsr.rspopupchangedate"
msgid "Change date"
@ -1042,15 +1037,16 @@ msgctxt "vpsr.rspopupeditevent"
msgid "Edit event..."
msgstr "Edytuj wydarzenie..."
#: vpsr.rspopupexporteventtoical
#: vpsr.rspopupexporttoical
msgctxt "vpsr.rspopupexporttoical"
msgid "Export to iCalendar file..."
msgstr ""
#: vpsr.rspopupimporteventfromical
#: vpsr.rspopupimportfromical
#, fuzzy
msgctxt "vpsr.rspopupimporteventfromical"
msgctxt "vpsr.rspopupimportfromical"
msgid "Import from iCalendar file(s)..."
msgstr "Import z pliku iCalendar"
msgstr "Import z pliku iCalendar..."
#: vpsr.rspopupresourcegroups
msgid "Overlay events"

View File

@ -1004,11 +1004,6 @@ msgstr ""
msgid "Add event..."
msgstr ""
#: vpsr.rspopupaddtaskfromical
msgctxt "vpsr.rspopupaddtaskfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""
#: vpsr.rspopupchangedate
msgid "Change date"
msgstr ""
@ -1021,12 +1016,13 @@ msgstr ""
msgid "Edit event..."
msgstr ""
#: vpsr.rspopupexporteventtoical
#: vpsr.rspopupexporttoical
msgctxt "vpsr.rspopupexporttoical"
msgid "Export to iCalendar file..."
msgstr ""
#: vpsr.rspopupimporteventfromical
msgctxt "vpsr.rspopupimporteventfromical"
#: vpsr.rspopupimportfromical
msgctxt "vpsr.rspopupimportfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""

View File

@ -1023,11 +1023,6 @@ msgctxt "vpsr.rspopupaddevent"
msgid "Add event..."
msgstr "Добавить событие..."
#: vpsr.rspopupaddtaskfromical
msgctxt "vpsr.rspopupaddtaskfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""
#: vpsr.rspopupchangedate
msgctxt "vpsr.rspopupchangedate"
msgid "Change date"
@ -1043,12 +1038,13 @@ msgctxt "vpsr.rspopupeditevent"
msgid "Edit event..."
msgstr "Изменить событие..."
#: vpsr.rspopupexporteventtoical
#: vpsr.rspopupexporttoical
msgctxt "vpsr.rspopupexporttoical"
msgid "Export to iCalendar file..."
msgstr ""
#: vpsr.rspopupimporteventfromical
msgctxt "vpsr.rspopupimporteventfromical"
#: vpsr.rspopupimportfromical
msgctxt "vpsr.rspopupimportfromical"
msgid "Import from iCalendar file(s)..."
msgstr ""

View File

@ -199,7 +199,6 @@ resourcestring
{Task Specific}
RSConfirmDeleteTask = 'Delete this task from your list?';
RSTaskPopupAdd = 'Add task...';
RSPopupAddTaskFromICal = 'Import from iCalendar file(s)...';
RSTaskPopupEdit = 'Edit task...';
RSTaskPopupDelete = 'Delete task...';
RSTaskTitleResource = 'Task list - '; {!!.01}
@ -208,8 +207,8 @@ resourcestring
{ Popup specific }
RSPopupAddEvent = 'Add event...';
RSPopupImportEventFromICal= 'Import from iCalendar file(s)...';
RSPopupExportEventToICal = 'Export to iCalendar file...';
RSPopupImportFromICal = 'Import from iCalendar file(s)...';
RSPopupExportToICal = 'Export to iCalendar file...';
RSPopupEditEvent = 'Edit event...';
RSPopupDeleteEvent = '&Delete event...';
RSPopupChangeDate = 'Change date';

View File

@ -82,7 +82,7 @@ type
mikAddTask, mikEditTask, mikDeleteTask,
mikAddContact, mikEditContact, mikDeleteContact,
mikImportEventFromICal, mikExportEventToICal,
mikImportTaskFromICal,
mikImportTaskFromICal, mikExportTaskToICal,
mikImportContactFromVCards, mikExportContactToVCard,
mikResourceGroups, mikNoOverlaidEvents,
mikChangeDate, mikCustomDate, mikToday, mikYesterday, mikTomorrow,
@ -95,8 +95,8 @@ type
RSPopupAddEvent, RSPopupEditEvent, RSPopupDeleteEvent,
RSTaskPopupAdd, RSTaskPopupEdit, RSTaskPopupDelete,
RSContactPopupAdd, RSContactPopupEdit, RSContactPopupDelete,
RSPopupImportEventFromICal, RSPopupExportEventToICal,
RSPopupAddTaskFromICal,
RSPopupImportFromICal, RSPopupExportToICal,
RSPopupImportFromICal, RSPopupExportToICal,
RSContactPopupImportVCards, RSContactPopupExportVCard,
RSPopupResourceGroups, RSNoOverlayedEvents,
RSPopupChangeDate, RSCustomDate, RSToday, RSYesterday, RSTomorrow,

View File

@ -387,6 +387,7 @@ type
procedure DeleteTask(Task: TVpTask);
function First: TVpTask;
function FirstByDay(Date: TDateTime): TVpTask;
procedure ExportICalFile(const AFileName: String; const ATasks: TVpTaskArr);
function ImportICalFile(const AFileName: String; APreview: Boolean = false;
ADefaultCategory: Integer = -1): TVpTaskArr;
function IndexOf(ATask: TVpTask): Integer;
@ -439,6 +440,7 @@ type
public
constructor Create(Owner: TVpTasks);
destructor Destroy; override;
function CreateICalTask(ACalendar: TVpICalendar): TVpICalToDo;
procedure LoadFromICalendar(AEntry: TVpICalToDo);
class function GetTaskPriority(APriority:Integer): TVpTaskPriority;
property Loading: Boolean read FLoading write FLoading;
@ -3146,6 +3148,31 @@ begin
inherited;
end;
function TVpTask.CreateICalTask(ACalendar: TVpICalendar): TVpICalToDo;
begin
Result := TVpICalToDo.Create(ACalendar);
Result.Summary := FDescription;
Result.Comment := FDetails;
Result.CreatedTime[false] := FCreatedOn;
Result.StartTime[false] := FCreatedOn;
Result.DueTime[false] := FDueDate;
if FComplete then
Result.CompletedTime[false] := FCompletedOn
else
Result.CompletedTime[false] := 0;
Result.Categories.Add(CategoryLabel(TVpCategoryType(FCategory)));
case TVpTaskPriority(FPriority) of
tpHigh: Result.Priority := 1;
tpNormal: Result.Priority := 5;
tpLow: Result.Priority := 9;
end;
if FComplete then
Result.Status := 'COMPLETED'
else
Result.Status := 'NEEDS-ACTION';
end;
{ Converts the priority numbers from ical files (1=highest ... 9=lowest) to the
TvPlanit type TVpTaskPriority. }
class function TVpTask.GetTaskPriority(APriority:Integer): TVpTaskPriority;
@ -3328,6 +3355,23 @@ begin
result := FTaskList.Count;
end;
procedure TVpTasks.ExportICalFile(const AFileName: String;
const ATasks: TVpTaskArr);
var
cal: TVpICalendar;
lTask: TVpTask;
begin
cal := TVpICalendar.Create;
try
for lTask in ATasks do
if lTask <> nil then
cal.Add(lTask.CreateICalTask(cal));
cal.SaveToFile(AFileName);
finally
cal.Free;
end;
end;
function TVpTasks.ImportICalFile(const AFileName: String;
APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpTaskArr;
const

View File

@ -1199,7 +1199,7 @@ begin
NewItem.Kind := mikSeparator;
FDefaultPopup.Items.Add(NewItem);
if RSPopupImportEventFromICal <> '' then begin
if RSPopupImportFromICal <> '' then begin
NewItem := TVpMenuItem.Create(Self); // Import from iCal
NewItem.Kind := mikImportEventFromICal;
NewItem.OnClick := PopupImportICalFile;
@ -1207,7 +1207,7 @@ begin
FDefaultPopup.Items.Add(NewItem);
end;
if RSPopupExportEventToICal <> '' then begin // Export ical
if RSPopupExportToICal <> '' then begin // Export ical
NewItem := TVpMenuItem.Create(Self);
NewItem.Kind := mikExportEventToICal;
NewItem.OnClick := PopupExportICalFile;

View File

@ -106,6 +106,8 @@ type
private
FSummary: String;
FComment: String;
FCreatedTime: TDateTime;
FCreatedTimeTZ: String;
FStartTime: TDateTime;
FStartTimeTZ: String;
FDueTime: TDateTime;
@ -120,24 +122,30 @@ type
function GetCategory(AIndex: integer): String;
function GetCategoryCount: Integer;
function GetCompletedTime(UTC: Boolean): TDateTime;
function GetCreatedTime(UTC: Boolean): TDateTime;
function GetDueTime(UTC: Boolean): TDateTime;
function GetStartTime(UTC: Boolean): TDateTime;
procedure SetCompletedTime(UTC: Boolean; const AValue: TDateTime);
procedure SetCreatedTime(UTC: Boolean; const AValue: TDateTime);
procedure SetDueTime(UTC: Boolean; const AValue: TDateTime);
procedure SetStartTime(UTC: Boolean; const AValue: TDateTime);
public
constructor Create(AOwner: TVpICalendar); override;
destructor Destroy; override;
procedure Analyze; override;
function Categories: TStrings;
procedure SaveToStrings(const AList: TStrings); 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 Summary: String read FSummary write FSummary;
property Comment: String read FComment write FComment;
property CreatedTime[UTC: Boolean]: TDateTime read GetCreatedTime write SetCreatedTime;
property StartTime[UTC: Boolean]: TDateTime read GetStartTime write SetStartTime;
property DueTime[UTC: Boolean]: TDateTime read GetDueTime write SetDueTime;
property CompletedTime[UTC: Boolean]: TDateTime read GetCompletedTime write SetCompletedTime;
property Category[AIndex: Integer]: String read GetCategory;
property CategoryCount: Integer read GetCategoryCount;
property PickedCategory: Integer read FPickedCategory write FPickedCategory;
property Priority: Integer read FPriority; // 0=undefined, 1-highest, 9=lowest
property Status: String read FStatus;
property Priority: Integer read FPriority write FPriority; // 0=undefined, 1-highest, 9=lowest
property Status: String read FStatus write FStatus;
end;
TVpICalendar = class
@ -647,6 +655,13 @@ begin
FSummary := item.Value;
'COMMENT':
FComment := item.Value;
'DTSTAMP':
begin
FCreatedTimeTZ := item.GetAttribute('TZID');
FCreatedTime := iCalDateTime(item.Value, isUTC);
if not isUTC then
FCreatedTime := FCalendar.LocalTimeToUTC(FCreatedTime, FCreatedTimeTZ);
end;
'DTSTART':
begin
FStartTimeTZ := item.GetAttribute('TZID');
@ -705,6 +720,13 @@ begin
Result := FCalendar.UTCToLocalTime(Result, FCompletedTimeTZ);
end;
function TVpICalToDo.GetCreatedTime(UTC: Boolean): TDateTime;
begin
Result := FCreatedTime;
if (Result > 0) and (not UTC) then
Result := FCalendar.UTCToLocalTime(Result, FCreatedTimeTZ);
end;
function TVpICalToDo.GetDueTime(UTC: Boolean): TDateTime;
begin
if FDueTime <> 0 then
@ -724,8 +746,102 @@ begin
end;
procedure TVpICalToDo.SaveToStrings(const AList: TStrings);
var
key: String;
dt: TDateTime;
begin
// to do...
AList.Add('BEGIN:TODO');
if FCreatedTimeTZ <> '' then
key := 'DTSTAMP;TZID=' + FCreatedTimeTZ + ':'
else
key := 'DTSTAMP:';
AList.Add(key + FormatDateTime(TIME_FORMAT_UTC, CreatedTime[true]));
if FSummary <> '' then
AList.Add('SUMMARY:' + FSummary);
if FComment <> '' then
AList.Add('COMMENT:' + FComment);
if FCategories.Count > 0 then
AList.Add('CATEGORIES:' + FCategories.DelimitedText);
// todo: check time zones!
if FStartTimeTZ <> '' then
key := 'DTSTART;TZID=' + FStartTimeTZ + ':'
else
key := 'DTSTART:';
AList.Add(key + FormatDateTime(TIME_FORMAT_UTC, StartTime[true]));
if FDueTimeTZ <> '' then
key := 'DUE;TZID=' + FDueTimeTZ + ':'
else
key := 'DUE:';
AList.Add(key + FormatDateTime(TIME_FORMAT_UTC, DueTime[true]));
dt := CompletedTime[true];
if dt > 0 then // 0 means here: "not completed yet"
begin
if FCompletedTimeTZ <> '' then
key := 'COMPLETE;TZID=' + FCompletedTimeTZ + ':'
else
key := 'COMPLETED:';
AList.Add(key + FormatDateTime(TIME_FORMAT_UTC, CompletedTime[true]));
end;
if FDuration <> 0 then
AList.Add('DURATION:' + Duration2iCalStr(FDuration)); // wp: Is this correct?
AList.Add('PRIORITY:' + IntToStr(FPriority));
if FStatus <> '' then
AList.Add('STATUS:' + FStatus);
AList.Add('END:TODO');
end;
procedure TVpICalToDo.SetCompletedTime(UTC: Boolean; const AValue: TDateTime);
begin
if AValue = NO_DATE then
FCompletedTime := NO_DATE
else
if UTC then
FCompletedTime := AValue
else
FCompletedTime := FCalendar.LocalTimeToUTC(AValue, FCompletedTimeTZ);
end;
procedure TVpICalToDo.SetCreatedTime(UTC: Boolean; const AValue: TDateTime);
begin
if AValue = NO_DATE then
FCreatedTime := NO_DATE
else
if UTC then
FCreatedTime := AValue
else
FCreatedTime := FCalendar.LocalTimeToUTC(AValue, FCreatedTimeTZ);
end;
procedure TVpICalToDo.SetDueTime(UTC: Boolean; const AValue: TDateTime);
begin
if AValue = NO_DATE then
FDueTime := NO_DATE
else
if UTC then
FDueTime := AValue
else
FDueTime := FCalendar.LocalTimeToUTC(AValue, FDueTimeTZ);
end;
procedure TVpICalToDo.SetStartTime(UTC: Boolean; const AValue: TDateTime);
begin
if AValue = NO_DATE then
FStartTime := NO_DATE
else
if UTC then
FStartTime := AValue
else
FStartTime := FCalendar.LocalTimeToUTC(AValue, FStartTimeTZ);
end;

View File

@ -1134,8 +1134,8 @@ procedure TVpMonthView.WMRButtonDown(var Msg: TLMRButtonDown);
{$ENDIF}
begin
inherited;
if not Assigned (PopupMenu) then begin
if not focused then
if (PopupMenu = FDefaultPopup) then begin
if not Focused then
SetFocus;
if FRightClickChangeDate then
mvSetDateByCoord (Point (Msg.XPos, Msg.YPos));

View File

@ -172,13 +172,8 @@ type
procedure SetColor(const Value: TColor); reintroduce;
procedure SetShowIcon(const v: Boolean);
procedure SetShowResourceName(Value: Boolean);
{ internal methods }
function GetPopupMenu: TPopupMenu; override;
procedure InitializeDefaultPopup;
procedure PopupAddTask(Sender: TObject);
procedure PopupAddFromICalFile(Sender: TObject);
procedure PopupDeleteTask(Sender: TObject);
procedure PopupEditTask(Sender: TObject);
procedure tlSetVScrollPos;
procedure tlCalcRowHeight;
procedure tlEditInPlace(Sender: TObject);
@ -196,6 +191,15 @@ type
procedure EndEdit(Sender: TObject);
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
{ Popup menu }
function GetPopupMenu: TPopupMenu; override;
procedure InitializeDefaultPopup;
procedure PopupAddTask(Sender: TObject);
procedure PopupDeleteTask(Sender: TObject);
procedure PopupEditTask(Sender: TObject);
procedure PopupExportToICalFile(Sender: TObject);
procedure PopupImportFromICalFile(Sender: TObject);
{ message handlers }
{$IFNDEF LCL}
procedure WMLButtonDown(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;
@ -220,6 +224,7 @@ type
procedure LinkHandler(Sender: TComponent; NotificationType: TVpNotificationType;
const Value: Variant); override;
function GetControlType: TVpItemType; override;
procedure ExportICalFile(const AFileName: String; const ATasks: TVpTaskArr);
function ImportICalFile(const AFileName: String; APreview: Boolean = false;
ADefaultCategory: Integer = -1): TVpTaskArr;
procedure PaintToCanvas(ACanvas: TCanvas; ARect: TRect; Angle: TVpRotationAngle);
@ -631,6 +636,13 @@ begin
Result := itTasks;
end;
procedure TVpTaskList.ExportICalFile(const AFileName: String;
const ATasks: TVpTaskArr);
begin
if Assigned(Datastore) and Assigned(Datastore.Resource) then
Datastore.Resource.Tasks.ExportICalFile(AFileName, ATasks);
end;
function TVpTaskList.ImportICalFile(const AFileName: String;
APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpTaskArr;
begin
@ -822,7 +834,7 @@ var
begin
inherited;
if not Assigned (PopupMenu) then begin
if (PopupMenu = FDefaultPopup) then begin
if not Focused then
SetFocus;
tlSetActiveTaskByCoord(Point(Msg.XPos, Msg.YPos));
@ -906,16 +918,22 @@ begin
FDefaultPopup.Items.Add(NewItem);
end;
if RSPopupAddTaskFromICal <> '' then begin // Import from iCal
if (RSPopupImportFromICal <> '') or (RSPopupExportToICal <> '') then begin
NewItem := TVpMenuItem.Create(Self);
NewItem.Kind := mikSeparator;
FDefaultPopup.Items.Add(NewItem);
NewItem := TVpMenuItem.Create(Self);
NewItem := TVpMenuItem.Create(Self); // Import from iCal
NewItem.Kind := mikImportTaskFromICal;
NewItem.OnClick := PopupAddFromICalFile;
NewItem.OnClick := PopupImportFromICalFile;
NewItem.Tag := 0;
FDefaultPopup.Items.Add(NewItem);
NewItem := TVpMenuItem.Create(Self); // Export to iCal
NewItem.Kind := mikExportTaskToICal;
NewItem.OnClick := PopupExportToICalFile;
NewItem.Tag := 1;
FDefaultPopup.Items.Add(NewItem);
end;
end;
@ -930,7 +948,50 @@ begin
tlSpawnTaskEditDialog(True);
end;
procedure TVpTaskList.PopupAddFromICalFile(Sender: TObject);
procedure TVpTaskList.PopupDeleteTask(Sender: TObject);
begin
if ReadOnly then
Exit;
if FActiveTask <> nil then begin
Repaint;
DeleteActiveTask(True);
end;
end;
procedure TVpTaskList.PopupEditTask(Sender: TObject);
begin
if ReadOnly then
Exit;
if FActiveTask <> nil then begin
Repaint;
{ edit this Task }
tlSpawnTaskEditDialog(False);
end;
end;
procedure TVpTaskList.PopupExportToICalFile(Sender: TObject);
var
dlg: TSaveDialog;
begin
if (not Assigned(Datastore)) or (not Assigned(Datastore.Resource)) or
(FActiveTask = nil)
then
exit;
dlg := TSaveDialog.Create(nil);
try
dlg.Title := RSSaveICalTitle;
dlg.Filter := RSICalFilter;
dlg.FileName := '';
dlg.Options := dlg.Options - [ofAllowMultiSelect] + [ofOverwritePrompt];
if dlg.Execute then
ExportICalFile(dlg.FileName, [FActiveTask]);
finally
dlg.Free;
end;
end;
procedure TVpTaskList.PopupImportFromICalFile(Sender: TObject);
var
dlg: TOpenDialog;
fn: String;
@ -955,27 +1016,6 @@ begin
end;
end;
procedure TVpTaskList.PopupDeleteTask(Sender: TObject);
begin
if ReadOnly then
Exit;
if FActiveTask <> nil then begin
Repaint;
DeleteActiveTask(True);
end;
end;
procedure TVpTaskList.PopupEditTask(Sender: TObject);
begin
if ReadOnly then
Exit;
if FActiveTask <> nil then begin
Repaint;
{ edit this Task }
tlSpawnTaskEditDialog(False);
end;
end;
procedure TVpTaskList.tlSpawnTaskEditDialog(IsNewTask: Boolean);
var
AllowIt: Boolean;

View File

@ -1236,7 +1236,7 @@ begin
NewItem.Kind := mikSeparator;
FDefaultPopup.Items.Add(NewItem);
if RSPopupImportEventFromICal <> '' then begin
if RSPopupImportFromICal <> '' then begin
NewItem := TVpMenuItem.Create(Self);
NewItem.Kind := mikImportEventFromICal; // Import from iCal
NewItem.OnClick := PopupImportFromICalFile;
@ -1244,7 +1244,7 @@ begin
FDefaultPopup.Items.Add(NewItem);
end;
if RSPopupExportEventToICal <> '' then begin
if RSPopupExportToICal <> '' then begin
NewItem := TVpMenuItem.Create(Self);
NewItem.Kind := mikExportEventToICal; // Export to iCal
NewItem.OnClick := PopupExportToICalFile;
@ -1832,7 +1832,7 @@ begin
{ Right button }
if Button = mbRight then
begin
if not Assigned(PopupMenu) then
if (PopupMenu <> FDefaultPopup) then
exit;
{ The mouse click landed inside the client area }