MeeGo 1.2 Harmattan Developer Documentation Develop for the Nokia N9

calendardemo.cpp Example File

calendardemo/src/calendardemo.cpp
 /****************************************************************************
 **
 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
 ** This file is part of the examples of the Qt Mobility Components.
 **
 ** $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 Nokia Corporation 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 <QtGui>
 #include <QDesktopServices>
 #include <qtorganizer.h>

 QTM_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
 #if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) || defined(Q_OS_WINCE)
     // These platforms need their menu items added directly to the menu bar.
     QMenuBar *optionsMenu = menuBar();
 #else
     QMenu *optionsMenu = new QMenu("&Options", this);
     #ifndef Q_OS_SYMBIAN
     // We add the options menu to the softkey manually later
     menuBar()->addMenu(optionsMenu);
     #endif
 #endif
     // Add editing options in the menu for Symbian (other platforms get buttons)
     QOrganizerManager defaultManager;
     QStringList 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()));

 #ifdef Q_OS_SYMBIAN
     // add the menu to the softkey for these pages
     m_monthPage->setMenu(optionsMenu);
     m_dayPage->setMenu(optionsMenu);
 #endif
 }

 void CalendarDemo::activateMonthPage()
 {
 #if !(defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6))
     menuBar()->setVisible(true);
 #endif
     m_monthPage->refresh();
     m_stackedWidget->setCurrentWidget(m_monthPage);
     m_switchViewAction->setText("&Open Day");
 }

 void CalendarDemo::activateDayPage()
 {
 #if !(defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6))
     menuBar()->setVisible(true);
 #endif
     m_dayPage->refresh();
     m_stackedWidget->setCurrentWidget(m_dayPage);
     m_switchViewAction->setText("View &Month");
 }

 void CalendarDemo::activateEditPage(const QOrganizerItem &item)
 {
     m_previousItem = item;
 #if !(defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6))
     menuBar()->setVisible(false);
 #endif
     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(m_manager->compatibleItem(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
 #if defined(Q_WS_MAEMO_5)
     newCollection.setMetaData("Name", "New calendar");
 #endif
     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;
 }