уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Не прошло и двух лет, как я снова вернулся к теме DevExpress и Google Calendar. За все эти почти два года много чего поменялось (и не всегда в лучшую сторону): несколько раз обновился DevExpress (это хорошо), вышли Delphi XE3, XE4, XE5, XE6 и XE7 (это тоже норм), Google установил квоты на использование Google Calendar API (не хорошо, но для нас пока и не критично). И на сегодняшний день у меня имеется следующий набор инструментов для рассмотрения темы DevExpress и Google Calendar: Delphi XE7 Enterprise и DevExpress v14.1.5 (v2014 vol 1.5).

Так как последний раз тема DevExpress и Google Calendar в Delphi затрагивалась давным давно, то, прежде всего, напомню о чем планировалось написать:

  1. Работа с ExpressScheduler в оффлайн. Обзор компонентов ExpressScheduler, основные моменты по организации календарей и работе с событиями, типы событий, экспорт календарей и т.д.
  2. Google Calendar API 3.0. Отличительные особенности этой версии API, работа с календарями и событиями в Google Calendar API, разработка компонентов и классов для работы с API в Delphi.
  3. ExpressScheduler + Google API. Доработка компонентов ExpressScheduler для работы с Google Calendar API, синхронизация календарей и событий и т.д.

Предвосхищая комментарии относительно того, что заявленная тема поста не соответствует содержанию, скажу следующее — соответствует в полной мере. Просто одна часть посетителей блога, заходя в блог из поисковика, знает и виртуозно владеет компонентами DevExpress Scheduler и ищет практически последние части этой серии, а именно — какому свойству компонента DevExpress соответствует  свойство объекта из Google Calendar API и как правильно получить сведения из календаря Google и т.д.  Другая часть наоборот — знает от А до Я работу с Google API, но только краем глаза видели работу DevExpress, но он (DevExpress) им край как нужен. А третьи не знают ни того ни другого. Вот и получается так, что для того, чтобы раскрыть тему если не на 100, то хотя бы на 90% надо рассматривать всю работу последовательно, затрагивая все вопросы — от работы компонентов в оффлайн до создания повторяющихся мероприятий в календаре с использованием API и их редактирования. Я решил рассматривать тему, начиная непосредственно с Delphi, т.е. с работы с компонентами. Так как работа ведется не регулярно и возможны перерывы на неопределенный срок, то в конце каждой статьи я буду оставлять ссылки на связанные статьи. В итоге должно получиться, что-то наподобие небольшой инструкции.

Сегодня я продолжаю рассмотрение компонентов DevExpress Scheduler и, согласно представленному выше плану, на очереди вопросы по организации календарей и работе с различными типами событий в Delphi.

Организация календарей в DevExpress Scheduler

В предыдущей статье «DevExpress и Google Calendar #1. Введение в ExpressScheduler» я вкратце рассказывал о том, как устроен компонент cxScheduler и о том, как работает редактор событий, в т.ч. и про работу с метками событий (Event Label).

По сути, метка события в DevExpress играет роль календаря, если говорить в терминах Google Calendar или любого другого сервиса организации расписаний. Однако при этом, Google возлагает на объект «Календарь» большее количество задач, нежели простое «закрашивание метки» — это и хранение информации о часовом поясе, и хранение информации об используемых оповещениях и т.д. В DevExpress же все относительно просто — Event Label содержит текст (название календаря) и цвет.

Чтобы получить список всех доступных меток, например, в ComboBox достаточно выполнить следующий код:

var
  I: Integer;
begin
  ComboBox1.Items.Clear;
  for I := 0 to EventLabels.Count-1 do
     ComboBox1.Items.Add(EventLabels[i].Caption);

Соответственно, чтобы заполнить список меток своими собственными, необходимо очистить его:

EventLabels.Clear;

и добавить свои собственные метки:

EventLabels.Add(clRed, 'Мой календарь')

Несмотря на то, что в последний раз тема Express Scheduler поднималась в блоге почти два года назад вопрос по работе с несколькими метками одного цвета так и остался открытым. Т.е. код:

EventLabels.Add(clRed, 'Мой календарь');
EventLabels.Add(clRed, 'Мой второй красный календарь');

так и приводит к тому, что вторую метку в редакторе событий пользователь так и не выберет никогда.

Все события в DevExpress Scheduler могут храниться в одном или нескольких компонентах TcxSchedulerStorage. При этом, если вы хотите хранить события в нескольких cxSchedulerStorage, то необходимо в свойстве TcxScheduler.Storege указать компонент TcxSchedulerAggregateStorage, а в свойстве TcxSchedulerAggregateStorage.Links указать все используемые TcxSchedulerStorage. То есть, схема подключения компонентов будет такая:

AggregateStorageТакая схема может оказаться удобной, например, если вы решите сделать так, чтобы события из разных календарей Google хранились в разных хранилищах (cxSchedulerStorage), что, в целом, довольно удобно и логично. В дальнейшем, мы воспользуемся этой возможностью.

Работа с событиями календаря в Express Scheduler

В DevExpress, как и в любой другой библиотеке для работы с календарями и расписаниями, имеется несколько типов событий. Так, не заглядывая в исходный код модулей DevExpress Scheduler, можно назвать следующие типы событий, использующихся практически повсеместно, в том числе и в Google Calendar:

  1. Однократное событие (Single Event) — событие, которое имеет дату и время начала/окончания. Самый часто используемый тип событий.
  2. Повторяющееся событие (Recurring Event) — событие, которое может повторяться два и более раз. Параметры таких событий обычно задаются в отдельном редакторе. Например, вы можете создать событие, которое будет повторяться еженедельно, по вторникам, 10 раз с момента начала события. Забегая вперед, скажу, что именно с этим типом событий у меня были самые серьезные проблемы при «скрещивании» DevExpress и Google Calendar.
  3. Событие на весь день (All-Day Event). По сути — это обычное событие, длящееся сутки или более. Обычно такие события отображаются в самом верху сетки расписания.

Посмотрим, какие типы событий предлагает нам DevExpress Scheduler:

TcxEventType = (etNone, etPattern, etOccurrence, etException, etCustom);
  • etNone — обычное пользовательское однократное событие без повторений (к этому же типу относится и All-Day Event)
  • etPattern — «шаблон». Событие, которое начинает цепочку повторяющегося события.
  • etOccurence — «вхождение». Событие, которое имеет своего «родителя», например, какое-либо событие из цепочки повторений (за исключением самого первого)
  • etException — «исключение». Тип события DevExpress, с помощью которого можно исключить из цепочки повторений какой-либо элемент. Например, с помощью etException создать такое событие «Начало 12.12.2014, повторять 10 раз каждую пятницу, кроме 19.12.2014«. В итоге DevExpress создаст цепочку из 10-ти событий, одно из которых (на 19.12.2014) будет иметь тип etException
  • etCustom — пользовательское событие с измененными сведениями о родителе.

Теперь посмотрим на работу с различными событиями в DevExpress глазами разработчика, т.е. в run-time.

Для создания нового экземпляра события используется метод TcxSchedulerStorage:

function createEvent: TcxSchedulerEvent;

Метод создает новое событие в календаре и возвращает объект TcxSchedulerEvent для дальнейшей работы.

Создание однократных событий

Самое простое, с точки зрения создания, событие — однократное. Создается оно достаточно просто:

cxSchedulerStorage1.BeginUpdate;
 try
   with cxSchedulerStorage1.createEvent do
      begin
        Caption:='Single Event';
        Location:='Место события';
        Message:='Описание события';
        Start:=Now;
        Finish:=IncHour(Start, 1);
        LabelColor:=clRed;
        Post;
      end;
 finally
   cxSchedulerStorage1.EndUpdate;
 end;

В итоге мы получим однократное событие продолжительностью в 1 час:
SingleEvent

Для создания события на весь день (All-Day Event) достаточно преобразовать код следующим образом:

 with cxSchedulerStorage1.createEvent do
   begin
     Caption:='All-Day Event';
     Location:='Место события';
     Message:='Описание события';
     Start:=Now;//указали дату начала события
     AllDayEvent:=True;//установили флаг "Событие на весь день"
     LabelColor:=clRed;
     Post;
   end;

В итоге, такое событие отобразится в сетке расписания следующим образом:
AllDayEvent
Создание повторяющихся событий

С этими событиями дела обстоят по-сложнее. Для указания правил повторения события нам необходимо задействовать свойство RecurrenceInfo созданного события. С помощью этого свойства мы можем создавать сколь угодно сложные повторения. Начнем с простого примера: создадим событие, которое будет повторяться ежедневно, 5 раз, начиная с текущего времени:

with cxSchedulerStorage1.createEvent do
   begin
     Caption:='Recurring Event';
     Location:='Место события';
     Message:='Описание события';
     Start:=Now;
     Finish:=IncHour(Now,1);
     //указываем тип события - шаблон
     EventType:=etPattern;
     //задаем параметры повторения
     RecurrenceInfo.Recurrence:=cxreDaily;//повторяем ежедневно
     RecurrenceInfo.DayType:=TcxDayType.cxdtEveryDay;//каждый день
     RecurrenceInfo.Count:=5;//5 раз
     Post;
     end;

В сетке расписания это событие будет отображаться следующим образом:
ReccuringEvent_1
Соответственно, чтобы создать событие, которое будет повторяться еженедельно по выходным, можно написать так:

 with cxSchedulerStorage1.createEvent do
     begin
       Caption:='Recurring Event';
       Location:='Место события';
       Message:='Описание события';
       EventType:=etPattern;
       Start:=Now;
       Finish:=IncHour(Now,1);
       RecurrenceInfo.Recurrence:=cxreDaily;
       RecurrenceInfo.DayType:=TcxDayType.cxdtWeekEndDay;
       RecurrenceInfo.Count:=5;
       Post;
     end;

В сетке расписания это будет выглядеть так:
ReccuringEvent_2

Создание исключений

Чтобы исключить из цепочки повторений какой-либо элемент необходимо использовать следующий метод TcxSchedulerStorage:

function CreateOccurrence(APattern: TcxSchedulerEvent; const ADate: TDateTime; AType: TcxEventType): TcxSchedulerEvent;

AParent — параметр должен указывать на событие тип которого etPattern
ADate — дата/время создания исключения
AType — тип события (etCustom или etException);
Для того, чтобы увидеть различия между типами событий etException и etCustom, создадим следующее повторяющееся событие:

   with cxSchedulerStorage1.createEvent do
     begin
       Caption:='Recurring Event';
       Location:='Место события';
       Message:='Событие на 7 дней';
       EventType:=etPattern;
       Start:=Now;
       Finish:=IncHour(Now,1);
       RecurrenceInfo.Recurrence:=cxreDaily;
       RecurrenceInfo.DayType:=TcxDayType.cxdtEveryDay;
       RecurrenceInfo.Count:=7;
       Post;
     end;

Событие непрерывно повторяется семь дней:
ReccuringEvent_3
Теперь изменим одно из повторений — создадим событие с типом etCustom, используя метод CreateOccurenc:

var AStart: TDateTime;
begin
  AStart:=incDay(cxSchedulerStorage1.Events[0].Start,2);
  with cxSchedulerStorage1.CreateOccurrence(cxSchedulerStorage1.Events[0], AStart, etCustom) do
    begin
      Start:=IncHour(AStart,1);
      Finish:=IncHour(Start,3);
    end;
 end;

Что мы здесь сделали:
1. Создали событие с типом etCustom.
2. При этом мы исключили из цепочки третье повторение (см. как определили AStart)
3. Для вновь созданного события установили новые сроки начала и окончания.
В итоге, сетка расписания приняла следующий вид:
ReccuringEvent_4
Третье повторение ни куда не делось, однако у него изменились сроки и значок повторения стал перечеркнутым. Аналогичный результат можно получить, если в работающем приложении вы мышкой перетащите любой из повторений в другое место сетки расписания. Если же вместо etCustom мы используем тип etException:

begin
  cxSchedulerStorage1.CreateOccurrence(cxSchedulerStorage1.Events[0], AStart, etException)
end;

то этот элемент цепочки будет скрыт из сетки расписание:
ReccuringEvent_5Думаю, что работа с событиями в DevExpress Scheduler стала более менее понятна? В дальнейшем нам пригодятся эти знания, когда мы будем читать данные из Google Calendar и создавать аналогичные в DevExpress.

Я не перечисляю здесь все доступные свойства и методы классов DevExpress, так как они все достаточно подробно расписаны в справке, но для быстрого знакомства с компонентами DevExpress Scheduler примеры, приведенные выше, пригодятся.

В заключение повторюсь ещё раз — эта и, скорее всего, следующие 1-2 статьи будут посвящены исключительно DevExpress. Кратко, сжато, но я постараюсь рассмотреть все основные моменты, которые далее будут использоваться в работе. Например, в следующий раз поговорим о, экспорте/импорте календарей во внешний файл. Только после этого начнется ряд статей про Google Calendar API и уже в заключение — готовое приложение для работы с Google Calendar в DevExpress. Так что, прошу набраться терпения и немного подождать. Благо свободного времени сейчас будет по-больше.

Книжная полка

Описание Подробно рассматривается библиотека FM, позволяющая создавать полнофункциональное программное обеспечение для операционных систем Windows и OS X, а также для смартфонов и планшетных компьютеров, работающих под управлением Android и iOS
купить книгу delphi на ЛитРес
Описание: Рассмотрены практические вопросы по разработке клиент-серверных приложений в среде Delphi 7 и Delphi 2005 с использованием СУБД MS SQL Server 2000, InterBase и Firebird. Приведена информация о теории построения реляционных баз данных и языке SQL. Освещены вопросы эксплуатации и администрирования СУБД.
купить книгу delphi на ЛитРес
Описание: Рассмотрены малоосвещенные вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные режимы их работы, особенности для протоколов TCP и UDP и др.
купить книгу delphi на ЛитРес
0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
5 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
trackback

[…] и Google Calendar #0. Введение« Следующая статья -«DevExpress и Google Calendar #2. Работа с событиями« (adsbygoogle = window.adsbygoogle || []).push({}); Понравилась […]

trackback

[…] DevExpress и Google Calendar #2. Работа с событиями; […]

Константин
Константин
19/12/2014 00:50

У DevExpress есть уже готовое решение для iCal-а
Подключить юнит cxSchedulerICalendar
и есть две замечательные функции
cxSchedulerICalendarImport и cxSchedulerICalendarExport
Немного блуждания по демкам и есть пример.
Правда загружается/выгружаются только те поля, которые есть в ExpressScheduler
Но это можно преодолеть написав нужных наследников и их зарегистрировав.

никол
никол
23/03/2017 23:50

а проекта-примера у вас случайно нету