usynccalendar.pas

来自「FMA is a free1 powerful phone editing to」· PAS 代码 · 共 1,530 行 · 第 1/4 页

PAS
1,530
字号
unit uSyncCalendar;

{
*******************************************************************************
* Descriptions: Calendar View
* $Source: /cvsroot/fma/fma/uSyncCalendar.pas,v $
* $Locker:  $
*
* Todo:
*
* Change Log:
* $Log: uSyncCalendar.pas,v $
*
}

interface

uses
  Windows, TntWindows, Messages, SysUtils, TntSysUtils, Variants, Classes, TntClasses, Graphics, TntGraphics,
  Controls, TntControls, Forms, TntForms, Dialogs, TntDialogs, ExtCtrls, TntExtCtrls, StdCtrls, TntStdCtrls,
  VpMonthView, VpTaskList, VpBase, VpBaseDS, VpDayView, VpData, uVBase, uVCalendar, uVpVDB, 
  Placemnt, uConnProgress, ImgList, Menus, TntMenus;

type
  TfrmCalendarView = class(TTntFrame)
    VpDayView: TVpDayView;
    VpControlLink: TVpControlLink;
    VpTaskList: TVpTaskList;
    VpMonthView: TVpMonthView;
    SplitterVertical: TTntSplitter;
    Panel: TTntPanel;
    SplitterHorizontal: TTntSplitter;
    FormStorage1: TFormStorage;
    ImageListCalPopup: TImageList;
    PopupMenuDayView: TTntPopupMenu;
    ForceasNotModifieDv: TTntMenuItem;
    ForceasModifiedDv: TTntMenuItem;
    ForceasNewEventDv: TTntMenuItem;
    PopupMenuTaskList: TTntPopupMenu;
    ForceasNotModifiedTl: TTntMenuItem;
    ForceasModifiedTl: TTntMenuItem;
    ForceasNewEventTl: TTntMenuItem;
    N1: TTntMenuItem;
    RecurItem1: TTntMenuItem;
    NextDay1: TTntMenuItem;
    NextWeek1: TTntMenuItem;
    NextMonth1: TTntMenuItem;
    NextYear1: TTntMenuItem;
    N2: TTntMenuItem;
    DownloadentireCalendar1: TTntMenuItem;
    N3: TTntMenuItem;
    DownloadEntireCalendar2: TTntMenuItem;
    N4: TTntMenuItem;
    CompletedStatus1: TTntMenuItem;
    CompletedToday1: TTntMenuItem;
    CompletedClear1: TTntMenuItem;
    N5: TTntMenuItem;
    Properties1: TTntMenuItem;
    N6: TTntMenuItem;
    Properties2: TTntMenuItem;
    N7: TTntMenuItem;
    ImportCalendar1: TTntMenuItem;
    ExportCalendar1: TTntMenuItem;
    OpenDialog1: TTntOpenDialog;
    TntSaveDialog1: TTntSaveDialog;
    N8: TTntMenuItem;
    ExportCalendar2: TTntMenuItem;
    ImportCalendar2: TTntMenuItem;
    procedure VpDayViewOwnerEditEvent(Sender: TObject; Event: TVpEvent;
      Resource: TVpResource; var AllowIt: Boolean);
    procedure VpTaskListOwnerEditTask(Sender: TObject; Task: TVpTask;
      Resource: TVpResource; var AllowIt: Boolean);
    procedure VpDayViewDrawIcons(Sender: TObject; Event: TVpEvent;
      var Icons: TVpDVIcons);
    procedure ForceasNotModifieDvClick(Sender: TObject);
    procedure ForceasModifiedDvClick(Sender: TObject);
    procedure ForceasNewEventDvClick(Sender: TObject);
    procedure ForceasNotModifiedTlClick(Sender: TObject);
    procedure ForceasModifiedTlClick(Sender: TObject);
    procedure ForceasNewEventTlClick(Sender: TObject);
    procedure RecurringClick(Sender: TObject);
    procedure PopupMenuDayViewPopup(Sender: TObject);
    procedure PopupMenuTaskListPopup(Sender: TObject);
    procedure DownloadentireCalendar1Click(Sender: TObject);
    procedure CompletedStatusClick(Sender: TObject);
    procedure Properties1Click(Sender: TObject);
    procedure ImportCalendar1Click(Sender: TObject);
    procedure btnSYNCClick(Sender: TObject);
    procedure btnDELClick(Sender: TObject);
    procedure Properties2Click(Sender: TObject);
    procedure VpDayViewBeforeEdit(Sender: TObject; Event: TVpEvent;
      var AllowIt: Boolean);
    procedure VpTaskListBeforeEdit(Sender: TObject; Task: TVpTask;
      var AllowIt: Boolean);
    procedure VpTaskListDrawIcons(Sender: TObject; Task: TVpTask;
      var Icons: TVpDVIcons);
    procedure VpTaskListCompleteChange(Sender: TObject; Task: TVpTask);
  private
    { Private declarations }
    ConflictVCalPhone,ConflictVCalPC: TVCalEntity;
    FSyncProgressDlg: TfrmConnect;
    VpDB: TVpVDataStore;
    CC: WideString;
    IsNew: Boolean;
    function DoShiftDate(Dt: TDateTime; Year,Month,Day: Word): TDateTime;
    function DoShiftEvent(Event: TVpEvent; Year,Month,Day: Word): boolean;
    { Sync }
    function Synchronize: boolean;
    function FullRefresh: boolean;
    function CheckInArray(A: array of widestring; S: Widestring): boolean;
    function FindCalObj(LUID: Widestring; var ACalEntity: TVCalEntity): Boolean;
    function ResolveConflict(EventName: WideString; Info:WideString; Appointment: Boolean): Integer;
    procedure VpBDAlert(Sender: TObject; Event: TVpEvent);
  protected
    FCalendar: TVCalendar;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure OnConnected;
    procedure OnConflictChanges(Sender: TObject; const TargetName, Option1Name, Option2Name: WideString);
    procedure ClearAlertFlag(EventRecordID: Integer; PostponeTime: TDateTime = 0);
    procedure ClearAllData; // USE WITH CARE!
    procedure LoadCalendar(FileName: WideString; IntoCal: TVCalendar = nil);
    procedure SaveCalendar(FileName: WideString; SaveCC: Boolean = True);
    { Properties }
    property DB: TVpVDataStore read VpDB;
    property Cal: TVCalendar read FCalendar;
  end;

implementation

uses
  gnugettext, gnugettexthelpers, DateUtils, uGlobal, uNewAlarm,
  Unit1, uLogger, VpMisc, uPromptConflict, uEditEvent, uEditTask, uConflictChanges, uDialogs;

{$R *.dfm}

constructor TfrmCalendarView.Create(AOwner: TComponent);
  var
    A: array[0..1] of char;
begin
  inherited;

  GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK, A, SizeOf(A));
  VpMonthView.WeekStartsOn := TVpDayType((Ord(A[0]) - Ord('0') + 1) mod 7);

  VpDB := TVpVDataStore.Create(Self);
  VpDB.OnAlert := VpBDAlert;

  VpDayView.DataStore := VpDB;
  VpMonthView.DataStore := VpDB;
  VpTaskList.DataStore := VpDB;

  FCalendar := TVCalendar.Create;
  VpDB.vCalendar := FCalendar;

  ConflictVCalPhone := TVCalEntity.Create;
  ConflictVCalPC := TVCalEntity.Create;

  IsNew := True;
end;

destructor TfrmCalendarView.Destroy;
begin
  VpDB.Free;
  FCalendar.Free;
  ConflictVCalPhone.Free;
  ConflictVCalPC.Free;

  inherited;
end;

procedure TfrmCalendarView.VpDayViewOwnerEditEvent(Sender: TObject;
  Event: TVpEvent; Resource: TVpResource; var AllowIt: Boolean);
var
  AAlarm: String;
begin
  inherited;
  AllowIt := False;
  with TfrmEditEvent.Create(nil) do
  try
    TntDatePickerStart.DateTime := Event.StartTime;
    TntTimePickerStart.DateTime := Event.StartTime;

    TntDatePickerEnd.DateTime := Event.EndTime;
    TntTimePickerEnd.DateTime := Event.EndTime;

    UpdateDudation;

    txtSubject.Text := Event.Description;
    // Use UserField0 for location value
    txtLocation.Text := Event.UserField0;

    TntComboBoxCategories.ItemIndex := Event.Category;

    // Use UserField1 for alarm datetime -- use [AlarmSet, AlarmAdv, AlarmAdvType] instead!
    if Event.AlarmSet then
      TntRadioGroupReminder.ItemIndex := 7
    else
      TntRadioGroupReminder.ItemIndex := 0;
    AdvMins := Event.AlarmAdv;
    AdvType := Event.AlarmAdvType;

    { Reccurence }
    case Event.RepeatCode of
      rtDaily:
        TntRadioGroupReccurence.ItemIndex := 1;
      rtWeekly:
        TntRadioGroupReccurence.ItemIndex := 2;
      rtMonthlyByDay:
        TntRadioGroupReccurence.ItemIndex := 3;
      rtYearlyByDay:
        TntRadioGroupReccurence.ItemIndex := 4;
      else
        TntRadioGroupReccurence.ItemIndex := 0;
    end;
    TntDatePickerReccurence.DateTime := Event.RepeatRangeEnd;
    TntTimePickerReccurence.DateTime := Event.RepeatRangeEnd;
    if Event.RepeatRangeEnd <> EmptyDate then
      TntComboBoxRangeEnd.ItemIndex := 1
    else
      TntComboBoxRangeEnd.ItemIndex := 0;

    // Use UserField2 for Weekly reccurence  
    WeekDays := Event.UserField2;

    if Event.UserField9 = '' then Event.UserField9 := '0';

    // edit event
    if ShowModal = mrOk then begin
      Event.StartTime := TntDatePickerStart.DateTime;
      Event.EndTime := TntDatePickerEnd.DateTime;

      Event.Description := txtSubject.Text;

      if Event.UserField0 <> txtLocation.Text then begin
        // Use UserField0 for location
        Event.UserField0 := txtLocation.Text;
        Event.Changed := True;
      end;

      if TntRadioGroupReminder.ItemIndex <> 0 then begin
        AAlarm := FloatToStr(TntDatePickerReminder.DateTime);
        Event.AlarmSet := True;
      end
      else begin
        AAlarm := '';
        Event.AlarmSet := False;
      end;
      Event.AlarmAdv := AdvMins;
      Event.AlarmAdvType := AdvType;
      // Use UserField1 for alarm datetime -- use [AlarmSet, AlarmAdv, AlarmAdvType] instead!
      if Event.UserField1 <> AAlarm then begin
        Event.UserField1 := AAlarm;
        Event.Changed := True;
      end;

      Event.AlertDisplayed := False;

      if TntComboBoxCategories.ItemIndex >= 0 then
        Event.Category := TntComboBoxCategories.ItemIndex
      else
        Event.Category := 0;

      case TntRadioGroupReccurence.ItemIndex of
        0: Event.RepeatCode := rtNone;
        1: Event.RepeatCode := rtDaily;
        2: Event.RepeatCode := rtWeekly;
        3: Event.RepeatCode := rtMonthlyByDay;
        4: Event.RepeatCode := rtYearlyByDay;
      end;
      if TntComboBoxRangeEnd.ItemIndex = 1 then
        Event.RepeatRangeEnd := TntDatePickerReccurence.DateTime
      else
        Event.RepeatRangeEnd := EmptyDate;

      if Event.UserField2 <> WeekDays then begin
        // Use UserField2 for Weekly reccurence
        Event.UserField2 := WeekDays;
        Event.Changed := True;
      end;

      if Event.Changed and (Event.UserField9 <> '0') then Event.UserField9 := '1';

      AllowIt := True;
    end;
  finally
    Free;
  end;
end;

procedure TfrmCalendarView.VpTaskListOwnerEditTask(Sender: TObject;
  Task: TVpTask; Resource: TVpResource; var AllowIt: Boolean);
var
  AAlarm: String;
  DtDone: TDateTime;
begin
  inherited;
  AllowIt := False;
  with TfrmEditTask.Create(nil) do
  try
    txtSubject.Text := Task.Description;

    if Task.Complete then begin
      chbCompleted.Checked := True;
      txtCompleted.Text := DateTimeToStr(Task.CompletedOn);
    end
    else begin
      chbCompleted.Checked := False;
      txtCompleted.Text := '';
    end;

    if Task.UserField9 = '' then Task.UserField9 := '0';

    dtpDate.DateTime := Task.DueDate;
    dtpTime.DateTime := Task.DueDate;

    Task.DueDate := 0;
    
    // Use UserField0 for reminder datetime
    if Task.UserField0 <> '' then begin
      chbReminder.Checked := True;
      dtpDate.DateTime := StrToFloat(Task.UserField0);
    end
    else begin
      chbReminder.Checked := False;
      dtpDate.DateTime := Now;
    end;
    dtpTime.DateTime := dtpDate.DateTime;
    chbReminderClick(self);

    // edit task
    if ShowModal = mrOk then begin
      Task.Description := txtSubject.Text;

      if txtNumber.Text <> '' then
        Task.Category := 1
      else
        Task.Category := 0;

      if chbReminder.Checked then
        AAlarm := FloatToStr(dtpDate.Date)
      else
        AAlarm := '';
      if Task.UserField0 <> AAlarm then begin
        // Use UserField0 for alarm datetime
        Task.UserField0 := AAlarm;
        Task.Changed := True;
      end;

      if chbCompleted.Checked then begin
        try
          DtDone := StrToDateTime(txtCompleted.Text);
          if DtDone <> Task.CompletedOn then begin
            Task.CompletedOn := DtDone;
            Task.Complete := True;
          end;
        except
        end;
      end
      else
        Task.Complete := False;

      if Task.Changed and (Task.UserField9 <> '0') then Task.UserField9 := '1';

      AllowIt := True;
    end;
  finally
    Free;
  end;
end;

procedure TfrmCalendarView.btnSYNCClick(Sender: TObject);
var
  isModified: Boolean;
  Err: WideString;
begin
  Form1.ActionSyncPhonebook.Enabled := False;
  FSyncProgressDlg := GetProgressDialog;
  try
    if Form1.CanShowProgress then
      FSyncProgressDlg.ShowProgress(Form1.FProgressLongOnly);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?