calendardemo.cpp Example File

calendardemo/src/calendardemo.cpp

  /****************************************************************************
  **
  ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
  ** Contact: http://www.qt-project.org/legal
  **
  ** This file is part of the examples of the Qt Toolkit.
  **
  ** $QT_BEGIN_LICENSE:BSD$
  ** You may use this file under the terms of the BSD license as follows:
  **
  ** "Redistribution and use in source and binary forms, with or without
  ** modification, are permitted provided that the following conditions are
  ** met:
  **   * Redistributions of source code must retain the above copyright
  **     notice, this list of conditions and the following disclaimer.
  **   * Redistributions in binary form must reproduce the above copyright
  **     notice, this list of conditions and the following disclaimer in
  **     the documentation and/or other materials provided with the
  **     distribution.
  **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
  **     of its contributors may be used to endorse or promote products derived
  **     from this software without specific prior written permission.
  **
  **
  ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  **
  ** $QT_END_LICENSE$
  **
  ****************************************************************************/

  #include "calendardemo.h"

  #include "monthpage.h"
  #include "daypage.h"
  #include "eventeditpage.h"
  #include "todoeditpage.h"
  #include "journaleditpage.h"
  #include "eventoccurrenceeditpage.h"
  #include "addcalendarpage.h"
  #include "editcalendarspage.h"
  #ifdef BUILD_VERSIT
  #include "qversitreader.h"
  #include "qversitwriter.h"
  #include "qversitorganizerimporter.h"
  #include "qversitorganizerexporter.h"
  #endif
  #include <QtWidgets>
  #include <QDesktopServices>
  #include <QtOrganizer/qorganizer.h>

  QTORGANIZER_USE_NAMESPACE

  CalendarDemo::CalendarDemo(QWidget *parent)
      :QMainWindow(parent),
      m_stackedWidget(0),
      m_monthPage(0),
      m_dayPage(0),
      m_eventEditPage(0),
      m_eventOccurrenceEditPage(0)
  {
      m_stackedWidget = new QStackedWidget(this);

      m_dayPage = new DayPage(m_stackedWidget);
      m_monthPage = new MonthPage(m_stackedWidget);
      m_eventEditPage = new EventEditPage(m_stackedWidget);
      m_todoEditPage = new TodoEditPage(m_stackedWidget);
      m_journalEditPage = new JournalEditPage(m_stackedWidget);
      m_eventOccurrenceEditPage = new EventOccurrenceEditPage(m_stackedWidget);
      m_addCalendarPage = new AddCalendarPage(m_stackedWidget);
      m_editCalendarsPage = new EditCalendarsPage(m_stackedWidget);

      //qRegisterMetaType<QOrganizerManager>("QOrganizerManager");
      qRegisterMetaType<QOrganizerItem>("QOrganizerItem");
      qRegisterMetaType<QOrganizerItemId>("QOrganizerItemId");
      qRegisterMetaType<QOrganizerCollection>("QOrganizerCollection");
      qRegisterMetaType<QOrganizerAbstractRequest::State>("QOrganizerAbstractRequest::State");

      connect(m_monthPage, SIGNAL(showDayPage(QDate)), this, SLOT(activateDayPage()), Qt::QueuedConnection);
      connect(m_monthPage, SIGNAL(showEditPage(const QOrganizerItem &)), this, SLOT(activateEditPage(const QOrganizerItem &)), Qt::QueuedConnection);
      connect(m_monthPage, SIGNAL(addNewEvent()), this, SLOT(addNewEvent()), Qt::QueuedConnection);
      connect(m_monthPage, SIGNAL(addNewTodo()), this, SLOT(addNewTodo()), Qt::QueuedConnection);
      connect(m_monthPage, SIGNAL(managerChanged(QOrganizerManager*)), this, SLOT(changeManager(QOrganizerManager*)), Qt::QueuedConnection);
      connect(m_monthPage, SIGNAL(managerChanged(QOrganizerManager*)), m_dayPage, SLOT(changeManager(QOrganizerManager*)), Qt::QueuedConnection);
      connect(m_monthPage, SIGNAL(currentDayChanged(QDate)), this, SLOT(updateSelectedDay(QDate)));
      connect(m_dayPage, SIGNAL(showMonthPage()), this, SLOT(activateMonthPage()), Qt::QueuedConnection);
      connect(m_dayPage, SIGNAL(showEditPage(const QOrganizerItem &)), this, SLOT(activateEditPage(const QOrganizerItem &)), Qt::QueuedConnection);
      connect(m_dayPage, SIGNAL(addNewEvent()), this, SLOT(addNewEvent()), Qt::QueuedConnection);
      connect(m_dayPage, SIGNAL(addNewTodo()), this, SLOT(addNewTodo()), Qt::QueuedConnection);
      connect(m_eventEditPage, SIGNAL(showDayPage()), this, SLOT(activateDayPage()), Qt::QueuedConnection);
      connect(m_todoEditPage, SIGNAL(showDayPage()), this, SLOT(activateDayPage()), Qt::QueuedConnection);
      connect(m_journalEditPage, SIGNAL(showDayPage()), this, SLOT(activateDayPage()), Qt::QueuedConnection);
      connect(m_eventOccurrenceEditPage, SIGNAL(showDayPage()), this, SLOT(activateDayPage()), Qt::QueuedConnection);
      connect(m_addCalendarPage, SIGNAL(showPreviousPage()), this, SLOT(activatePreviousPage()), Qt::QueuedConnection);
      connect(m_editCalendarsPage, SIGNAL(showAddCalendarPage(QOrganizerManager*,QOrganizerCollection*)), this, SLOT(editExistingCalendar(QOrganizerManager*,QOrganizerCollection*)), Qt::QueuedConnection);
      connect(m_editCalendarsPage, SIGNAL(showPreviousPage()), this, SLOT(activateMonthPage()), Qt::QueuedConnection);
      connect(m_editCalendarsPage, SIGNAL(addClicked()), this, SLOT(addCalendar()), Qt::QueuedConnection);

      // Connect to the save and remove request status change signals
      connect(&m_saveReq, SIGNAL(stateChanged(QOrganizerAbstractRequest::State)),
              this, SLOT(saveReqStateChanged(QOrganizerAbstractRequest::State)));
      connect(&m_remReq, SIGNAL(stateChanged(QOrganizerAbstractRequest::State)),
              this, SLOT(removeReqStateChanged(QOrganizerAbstractRequest::State)));

      m_monthPage->init();

      m_stackedWidget->addWidget(m_monthPage);
      m_stackedWidget->addWidget(m_dayPage);
      m_stackedWidget->addWidget(m_eventEditPage);
      m_stackedWidget->addWidget(m_todoEditPage);
      m_stackedWidget->addWidget(m_journalEditPage);
      m_stackedWidget->addWidget(m_eventOccurrenceEditPage);
      m_stackedWidget->addWidget(m_addCalendarPage);
      m_stackedWidget->addWidget(m_editCalendarsPage);
      m_stackedWidget->setCurrentIndex(0);

      setCentralWidget(m_stackedWidget);
      buildMenu();

      activateMonthPage();
  }

  CalendarDemo::~CalendarDemo()
  {

  }

  void CalendarDemo::buildMenu()
  {
      // Build Options menu
      QMenu *optionsMenu = new QMenu("&Options", this);
      menuBar()->addMenu(optionsMenu);
      // Add editing options in the menu
      QOrganizerManager defaultManager;
      QList<QOrganizerItemType::ItemType> supportedItemTypes = defaultManager.supportedItemTypes();
      if (supportedItemTypes.contains(QOrganizerItemType::TypeEvent)) {
          QAction* addEventAction = optionsMenu->addAction("Add E&vent");
          connect(addEventAction, SIGNAL(triggered(bool)), this, SLOT(addNewEvent()));
      }
      if (supportedItemTypes.contains(QOrganizerItemType::TypeTodo)) {
          QAction* addTodoAction = optionsMenu->addAction("Add &Todo");
          connect(addTodoAction, SIGNAL(triggered(bool)), this, SLOT(addNewTodo()));
      }
      if (supportedItemTypes.contains(QOrganizerItemType::TypeJournal)) {
          QAction* addJournalAction = optionsMenu->addAction("Add &Journal");
          connect(addJournalAction, SIGNAL(triggered(bool)), this, SLOT(addNewJournal()));
      }
      optionsMenu->addSeparator();
      QAction* editAction = optionsMenu->addAction("&Edit");
      connect(editAction, SIGNAL(triggered(bool)), this, SLOT(editItem()));
      QAction* removeAction = optionsMenu->addAction("&Remove");
      connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(removeItem()));
      optionsMenu->addSeparator();
      m_switchViewAction = optionsMenu->addAction("&Open Day");
      connect(m_switchViewAction, SIGNAL(triggered(bool)), this, SLOT(switchView()));
      optionsMenu->addSeparator();
      QAction* addHugeEntries = optionsMenu->addAction("Add Test Events");
      connect(addHugeEntries, SIGNAL(triggered(bool)), this, SLOT(addEvents()));
      QAction* importItems = optionsMenu->addAction("&Import Items...");
      connect(importItems, SIGNAL(triggered(bool)), this, SLOT(importItems()));
      QAction* exportItems = optionsMenu->addAction("Ex&port Items...");
      connect(exportItems, SIGNAL(triggered(bool)), this, SLOT(exportItems()));
      QAction* deleteAllEntries = optionsMenu->addAction("Delete All Items");
      connect(deleteAllEntries, SIGNAL(triggered(bool)), this, SLOT(deleteAllEntries()));
      QAction* addCalendar = optionsMenu->addAction("New calendar");
      connect(addCalendar, SIGNAL(triggered(bool)), this, SLOT(addCalendar()));
      QAction* editCalendar = optionsMenu->addAction("Edit calendars");
      connect(editCalendar, SIGNAL(triggered(bool)), this, SLOT(editCalendar()));
  }

  void CalendarDemo::activateMonthPage()
  {
      menuBar()->setVisible(true);
      m_monthPage->refresh();
      m_stackedWidget->setCurrentWidget(m_monthPage);
      m_switchViewAction->setText("&Open Day");
  }

  void CalendarDemo::activateDayPage()
  {
      menuBar()->setVisible(true);
      m_dayPage->refresh();
      m_stackedWidget->setCurrentWidget(m_dayPage);
      m_switchViewAction->setText("View &Month");
  }

  void CalendarDemo::activateEditPage(const QOrganizerItem &item)
  {
      m_previousItem = item;
      menuBar()->setVisible(false);
      if (item.type() == QOrganizerItemType::TypeEvent) {
          QOrganizerEvent event = static_cast<QOrganizerEvent>(item);
          m_dayPage->dayChanged(event.startDateTime().date()); // edit always comes back to day page
          m_eventEditPage->eventChanged(m_manager, event);
          m_stackedWidget->setCurrentWidget(m_eventEditPage);
      } else if (item.type() == QOrganizerItemType::TypeTodo) {
          QOrganizerTodo todo = static_cast<QOrganizerTodo>(item);
          m_dayPage->dayChanged(todo.startDateTime().date()); // edit always comes back to day page
          m_todoEditPage->todoChanged(m_manager, todo);
          m_stackedWidget->setCurrentWidget(m_todoEditPage);
      } else if (item.type() == QOrganizerItemType::TypeJournal) {
          QOrganizerJournal journal = static_cast<QOrganizerJournal>(item);
          m_dayPage->dayChanged(journal.dateTime().date()); // edit always comes back to day page
          m_journalEditPage->journalChanged(m_manager, journal);
          m_stackedWidget->setCurrentWidget(m_journalEditPage);
      } else if (item.type() == QOrganizerItemType::TypeEventOccurrence) {
          QOrganizerEventOccurrence eventOccurrence = static_cast<QOrganizerEventOccurrence>(item);
          QMessageBox msgBox;
          msgBox.setText(tr("This is a recurring event"));
          msgBox.setInformativeText(tr("Do you want to open this occurrence or the recurring event series?"));
          QAbstractButton *occurrenceButton = msgBox.addButton(tr("Occurrence"), QMessageBox::ActionRole);
          QAbstractButton *seriesButton = msgBox.addButton(tr("Series"), QMessageBox::ActionRole);

          msgBox.exec();
          if (msgBox.clickedButton() == seriesButton) {
              QOrganizerItemId parentEventId = eventOccurrence.parentId();
              QOrganizerEvent parentEvent = m_manager->item(parentEventId);
              m_dayPage->dayChanged(parentEvent.startDateTime().date()); // edit always comes back to day page
              m_eventEditPage->eventChanged(m_manager, parentEvent);
              m_stackedWidget->setCurrentWidget(m_eventEditPage);
          } else if (msgBox.clickedButton() == occurrenceButton) {
              m_dayPage->dayChanged(eventOccurrence.startDateTime().date()); // edit always comes back to day page
              m_eventOccurrenceEditPage->eventOccurrenceChanged(m_manager, eventOccurrence);
              m_stackedWidget->setCurrentWidget(m_eventOccurrenceEditPage);
          }

      }
      // TODO:
      //else if (item.type() == QOrganizerItemType::TypeNote)
  }

  void CalendarDemo::activatePreviousPage()
  {
      if (m_previousPage == m_stackedWidget->indexOf(m_monthPage))
          activateMonthPage();
      else if (m_previousPage == m_stackedWidget->indexOf(m_dayPage))
          activateDayPage();
      else if (m_previousPage == m_stackedWidget->indexOf(m_editCalendarsPage))
          editCalendar();
      else
          activateEditPage(m_previousItem);
  }

  void CalendarDemo::addNewEvent()
  {
      QOrganizerEvent newEvent;
      QDateTime time(m_currentDate);
      newEvent.setStartDateTime(time);
      time = time.addSecs(60*30); // add 30 minutes to end time
      newEvent.setEndDateTime(time);
      activateEditPage(newEvent);
  }

  void CalendarDemo::addNewTodo()
  {
      QOrganizerTodo newTodo;
      QDateTime time(m_currentDate);
      newTodo.setStartDateTime(time);
      time = time.addSecs(60*30); // add 30 minutes to due time
      newTodo.setDueDateTime(time);
      activateEditPage(newTodo);
  }

  void CalendarDemo::addNewJournal()
  {
      QOrganizerJournal newJournal;
      QDateTime time(m_currentDate);
      newJournal.setDateTime(time);
      activateEditPage(newJournal);
  }

  void CalendarDemo::switchView()
  {
      if (m_stackedWidget->currentWidget() == m_dayPage) {
          activateMonthPage();
      } else if (m_stackedWidget->currentWidget() == m_monthPage) {
          activateDayPage();
      }
  }

  void CalendarDemo::editItem()
  {
      if (m_stackedWidget->currentWidget() == m_dayPage) {
          m_dayPage->editItem();
      } else if (m_stackedWidget->currentWidget() == m_monthPage) {
          m_monthPage->editItem();
      }
  }

  void CalendarDemo::removeItem()
  {
      if (m_stackedWidget->currentWidget() == m_dayPage) {
          m_dayPage->removeItem();
      } else if (m_stackedWidget->currentWidget() == m_monthPage) {
          m_monthPage->removeItem();
      }
  }

  void CalendarDemo::addEvents()
  {
      QList<QOrganizerItem> items;

      // Create a large number of events asynchronously
      QOrganizerCollectionId defaultCollectionId = m_manager->defaultCollection().id();
      for(int index=0 ; index <  100 ; index++) {
          QOrganizerItem item;
          item.setType(QOrganizerItemType::TypeEvent);
          item.setDescription(QString("Event %1").arg(index));
          item.setDisplayLabel(QString("Subject for event %1").arg(index + 1));

          // Set the start date to index to add events to next 5000 days
          QOrganizerEventTime timeRange;
          timeRange.setStartDateTime(QDateTime::currentDateTime().addDays(index));
          timeRange.setEndDateTime(QDateTime::currentDateTime().addDays(index).addSecs(60 * 60));
          item.saveDetail(&timeRange);

          item.setCollectionId(defaultCollectionId);

          items.append(item);
      }

      // Now create a save request and execute it
      m_saveReq.setItems(items);
      m_saveReq.setManager(m_manager);
      m_saveReq.start();
  }

  void CalendarDemo::importItems()
  {
  #ifdef BUILD_VERSIT
      QString messageTitle(tr("Import of Items failed"));
      if (!m_manager) {
          QMessageBox::warning(this, messageTitle, tr("No manager selected; cannot import"));
          return;
      }
      QString docPath = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
      if (docPath.isEmpty())
          docPath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
      if (docPath.isEmpty())
          docPath = ".";
      QString fileName = QFileDialog::getOpenFileName(this,
         tr("Select iCalendar file"), docPath, tr("iCalendar files (*.ics)"));

      // user chose to cancel file dialog?
      if (fileName.isEmpty())
           return;

      QFile file(fileName);
      if (!file.open(QIODevice::ReadOnly) || !file.isReadable()){
          QMessageBox::warning(this, messageTitle, tr("Unable to read from file: %1").arg(fileName));
          return;
      }
      QVersitReader reader;
      reader.setDevice(&file);
      if (!reader.startReading() || !reader.waitForFinished()) {
          QMessageBox::warning(this, messageTitle, tr("Versit reader failed: %1").arg(reader.error()));
          return;
      }
      QVersitOrganizerImporter importer;
      QList<QOrganizerItem> allItems;
      QString errorMessage;
      foreach (const QVersitDocument& document, reader.results()) {
          if (!importer.importDocument(document)) {
              errorMessage += tr("Import failed,");
              QMap<int, QVersitOrganizerImporter::Error>::const_iterator iterator = importer.errorMap().constBegin();
              while(iterator != importer.errorMap().constEnd()){
                  switch (iterator.value()){
                  case QVersitOrganizerImporter::InvalidDocumentError:
                      errorMessage += QString(" index %1:").arg(iterator.key());
                      errorMessage += tr("One of the documents is not an iCalendar file");
                  break;
                  case QVersitOrganizerImporter::EmptyDocumentError:
                      errorMessage += QString(" index %1:").arg(iterator.key());
                      errorMessage += tr("One of the documents is empty");
                  break;
                  default:
                      errorMessage += QString(" index %1:").arg(iterator.key());
                      errorMessage += tr("Unknown error");
                  }
                  ++iterator;
              }
              errorMessage += QLatin1String("\n");
              continue;
          }
          QList<QOrganizerItem> items = importer.items();
          foreach (const QOrganizerItem& item, items) {
              allItems.append(item);
          }
      }
      if (!errorMessage.isEmpty())
          QMessageBox::warning(this, messageTitle, errorMessage);

      m_manager->saveItems(&allItems);
      m_monthPage->refresh();
      m_dayPage->refresh();
  #endif
  }

  void CalendarDemo::exportItems()
  {
  #ifdef BUILD_VERSIT
      QString messageTitle(tr("Export of Items failed"));
      if (!m_manager) {
          QMessageBox::warning(this, messageTitle, tr("No manager selected; cannot export"));
          return;
      }
      QString docPath = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
      if (docPath.isEmpty())
          docPath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
      if (docPath.isEmpty())
          docPath = ".";
      docPath.append("/calendar.ics");
      QString fileName = QFileDialog::getSaveFileName(this, tr("Save iCalendar"),
                                                      docPath,
                                                      tr("iCalendar files (*.ics)"));
      // user chose to cancel file dialog?
      if (fileName.isEmpty())
           return;

      QFile file(fileName);
      if (!file.open(QIODevice::WriteOnly) || !file.isWritable()) {
          QMessageBox::warning(this, messageTitle, tr("Unable to write to file: %1").arg(fileName));
          return;
      }
      QList<QOrganizerItem> items(m_manager->itemsForExport());
      QVersitOrganizerExporter exporter;
      QString errorMessage;
      if (!exporter.exportItems(items)) {
              errorMessage += tr("Export failed,");
              QMap<int, QVersitOrganizerExporter::Error>::const_iterator iterator = exporter.errorMap().constBegin();
              while(iterator != exporter.errorMap().constEnd()){
                  switch (iterator.value()){
                  case QVersitOrganizerExporter::EmptyOrganizerError:
                      errorMessage += QString(" index %1:").arg(iterator.key());
                      errorMessage += tr("One of the documents is not an iCalendar file");
                  break;
                  case QVersitOrganizerExporter::UnknownComponentTypeError:
                      errorMessage += QString(" index %1:").arg(iterator.key());
                      errorMessage += tr("One of the components in the iCalendar file is"
                                         " not supported");
                  break;
                  case QVersitOrganizerExporter::UnderspecifiedOccurrenceError:
                      errorMessage += QString(" index %1:").arg(iterator.key());
                      errorMessage += tr("An event or todo exception was found which"
                                         " did not specify both its parent and a specifier for"
                                         " which instance to override");
                  break;
                  default:
                      errorMessage += QString(" index %1:%2 ").arg(iterator.key())
                                                             .arg(tr("Unknown error"));
                  }
                  ++iterator;
              }
              errorMessage += QLatin1String("\n");
          if (!errorMessage.isEmpty()){
              QMessageBox::warning(this, messageTitle, errorMessage);
              return;
          }
      }
      QVersitDocument document = exporter.document();
      QVersitWriter writer;
      writer.setDevice(&file);
      if (!writer.startWriting(QList<QVersitDocument>() << document)
          || !writer.waitForFinished()) {
          QMessageBox::warning(this, messageTitle,
              tr("Versit writing of organizer items failed: %1").arg(writer.error()));
      }
  #endif
  }

  void CalendarDemo::deleteAllEntries()
  {
      // Fetch all the entries
      QList<QOrganizerItemId> ids = m_manager->itemIds();

      if(ids.count()) {
          m_remReq.setItemIds(ids);
          m_remReq.setManager(m_manager);
          m_remReq.start();
      }
  }

  void CalendarDemo::addCalendar()
  {
      // Get default collection
      QOrganizerCollection defaultCollection = m_manager->defaultCollection();

      QOrganizerCollection newCollection = defaultCollection;
      newCollection.setId(QOrganizerCollectionId()); // reset collection id
      m_addCalendarPage->calendarChanged(m_manager, newCollection);

      m_previousPage = m_stackedWidget->currentIndex();
      m_stackedWidget->setCurrentWidget(m_addCalendarPage);
  }

  void CalendarDemo::editCalendar()
  {
      m_editCalendarsPage->showPage(m_manager);
      m_previousPage = m_stackedWidget->currentIndex();
      m_stackedWidget->setCurrentWidget(m_editCalendarsPage);
  }

  void CalendarDemo::editExistingCalendar(QOrganizerManager *manager, QOrganizerCollection* calendar)
  {
      m_addCalendarPage->calendarChanged(manager, *calendar);
      m_previousPage = m_stackedWidget->currentIndex();
      m_stackedWidget->setCurrentWidget(m_addCalendarPage);
  }

  void CalendarDemo::saveReqStateChanged(QOrganizerAbstractRequest::State reqState)
  {
      if(QOrganizerAbstractRequest::ActiveState == reqState) {
          // Request started. Show a progress or wait dialog
          m_progressDlg = new QProgressDialog("Saving events..", "Cancel", 100, 100, this);
          connect(m_progressDlg, SIGNAL(canceled()), &m_saveReq, SLOT(cancel()));
          m_progressDlg->show();
      } else if (QOrganizerAbstractRequest::FinishedState == reqState ||
                 QOrganizerAbstractRequest::CanceledState == reqState) {
          // Request finished or cancelled. Stop showing the progress dialog and refresh
          m_progressDlg->hide();
          m_monthPage->refresh();
          m_dayPage->refresh();
      }
  }

  void CalendarDemo::removeReqStateChanged(QOrganizerAbstractRequest::State reqState)
  {
      if(QOrganizerAbstractRequest::ActiveState == reqState) {
          // Request started. Show a progress or wait dialog
          m_progressDlg = new QProgressDialog("Removing events..", "Cancel", 100, 100, this);
          connect(m_progressDlg, SIGNAL(canceled()), &m_remReq, SLOT(cancel()));
          m_progressDlg->show();
      } else if (QOrganizerAbstractRequest::FinishedState == reqState ||
                 QOrganizerAbstractRequest::CanceledState == reqState) {
          // Request finished or cancelled. Stop showing the progress dialog and refresh
          m_progressDlg->hide();
          m_monthPage->refresh();
          m_dayPage->refresh();
      }
  }

  void CalendarDemo::changeManager(QOrganizerManager *manager)
  {
      m_manager = manager;
  }

  void CalendarDemo::updateSelectedDay(const QDate& date)
  {
      m_dayPage->dayChanged(date);
      m_currentDate = date;
  }