| 1 | /**************************************************************************** |
| 2 | ** |
| 3 | ** Copyright (C) 2015 The Qt Company Ltd. |
| 4 | ** Contact: http://www.qt.io/licensing/ |
| 5 | ** |
| 6 | ** This file is part of the examples of the Qt Toolkit. |
| 7 | ** |
| 8 | ** $QT_BEGIN_LICENSE:BSD$ |
| 9 | ** You may use this file under the terms of the BSD license as follows: |
| 10 | ** |
| 11 | ** "Redistribution and use in source and binary forms, with or without |
| 12 | ** modification, are permitted provided that the following conditions are |
| 13 | ** met: |
| 14 | ** * Redistributions of source code must retain the above copyright |
| 15 | ** notice, this list of conditions and the following disclaimer. |
| 16 | ** * Redistributions in binary form must reproduce the above copyright |
| 17 | ** notice, this list of conditions and the following disclaimer in |
| 18 | ** the documentation and/or other materials provided with the |
| 19 | ** distribution. |
| 20 | ** * Neither the name of The Qt Company Ltd nor the names of its |
| 21 | ** contributors may be used to endorse or promote products derived |
| 22 | ** from this software without specific prior written permission. |
| 23 | ** |
| 24 | ** |
| 25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
| 36 | ** |
| 37 | ** $QT_END_LICENSE$ |
| 38 | ** |
| 39 | ****************************************************************************/ |
| 40 | |
| 41 | #include "calendardemo.h" |
| 42 | |
| 43 | #include "monthpage.h" |
| 44 | #include "daypage.h" |
| 45 | #include "eventeditpage.h" |
| 46 | #include "todoeditpage.h" |
| 47 | #include "journaleditpage.h" |
| 48 | #include "eventoccurrenceeditpage.h" |
| 49 | #include "addcalendarpage.h" |
| 50 | #include "editcalendarspage.h" |
| 51 | #ifdef BUILD_VERSIT |
| 52 | #include "qversitreader.h" |
| 53 | #include "qversitwriter.h" |
| 54 | #include "qversitorganizerimporter.h" |
| 55 | #include "qversitorganizerexporter.h" |
| 56 | #endif |
| 57 | #include <QtWidgets> |
| 58 | #include <QDesktopServices> |
| 59 | #include <QtOrganizer/qorganizer.h> |
| 60 | |
| 61 | QTORGANIZER_USE_NAMESPACE |
| 62 | |
| 63 | CalendarDemo::CalendarDemo(QWidget *parent) |
| 64 | :QMainWindow(parent), |
| 65 | m_stackedWidget(0), |
| 66 | m_monthPage(0), |
| 67 | m_dayPage(0), |
| 68 | m_eventEditPage(0), |
| 69 | m_eventOccurrenceEditPage(0) |
| 70 | { |
| 71 | m_stackedWidget = new QStackedWidget(this); |
| 72 | |
| 73 | m_dayPage = new DayPage(m_stackedWidget); |
| 74 | m_monthPage = new MonthPage(m_stackedWidget); |
| 75 | m_eventEditPage = new EventEditPage(m_stackedWidget); |
| 76 | m_todoEditPage = new TodoEditPage(m_stackedWidget); |
| 77 | m_journalEditPage = new JournalEditPage(m_stackedWidget); |
| 78 | m_eventOccurrenceEditPage = new EventOccurrenceEditPage(m_stackedWidget); |
| 79 | m_addCalendarPage = new AddCalendarPage(m_stackedWidget); |
| 80 | m_editCalendarsPage = new EditCalendarsPage(m_stackedWidget); |
| 81 | |
| 82 | //qRegisterMetaType<QOrganizerManager>("QOrganizerManager"); |
| 83 | qRegisterMetaType<QOrganizerItem>(typeName: "QOrganizerItem" ); |
| 84 | qRegisterMetaType<QOrganizerItemId>(typeName: "QOrganizerItemId" ); |
| 85 | qRegisterMetaType<QOrganizerCollection>(typeName: "QOrganizerCollection" ); |
| 86 | qRegisterMetaType<QOrganizerAbstractRequest::State>(typeName: "QOrganizerAbstractRequest::State" ); |
| 87 | |
| 88 | connect(sender: m_monthPage, SIGNAL(showDayPage(QDate)), receiver: this, SLOT(activateDayPage()), Qt::QueuedConnection); |
| 89 | connect(sender: m_monthPage, SIGNAL(showEditPage(const QOrganizerItem &)), receiver: this, SLOT(activateEditPage(const QOrganizerItem &)), Qt::QueuedConnection); |
| 90 | connect(sender: m_monthPage, SIGNAL(addNewEvent()), receiver: this, SLOT(addNewEvent()), Qt::QueuedConnection); |
| 91 | connect(sender: m_monthPage, SIGNAL(addNewTodo()), receiver: this, SLOT(addNewTodo()), Qt::QueuedConnection); |
| 92 | connect(sender: m_monthPage, SIGNAL(managerChanged(QOrganizerManager*)), receiver: this, SLOT(changeManager(QOrganizerManager*)), Qt::QueuedConnection); |
| 93 | connect(sender: m_monthPage, SIGNAL(managerChanged(QOrganizerManager*)), receiver: m_dayPage, SLOT(changeManager(QOrganizerManager*)), Qt::QueuedConnection); |
| 94 | connect(sender: m_monthPage, SIGNAL(currentDayChanged(QDate)), receiver: this, SLOT(updateSelectedDay(QDate))); |
| 95 | connect(sender: m_dayPage, SIGNAL(showMonthPage()), receiver: this, SLOT(activateMonthPage()), Qt::QueuedConnection); |
| 96 | connect(sender: m_dayPage, SIGNAL(showEditPage(const QOrganizerItem &)), receiver: this, SLOT(activateEditPage(const QOrganizerItem &)), Qt::QueuedConnection); |
| 97 | connect(sender: m_dayPage, SIGNAL(addNewEvent()), receiver: this, SLOT(addNewEvent()), Qt::QueuedConnection); |
| 98 | connect(sender: m_dayPage, SIGNAL(addNewTodo()), receiver: this, SLOT(addNewTodo()), Qt::QueuedConnection); |
| 99 | connect(sender: m_eventEditPage, SIGNAL(showDayPage()), receiver: this, SLOT(activateDayPage()), Qt::QueuedConnection); |
| 100 | connect(sender: m_todoEditPage, SIGNAL(showDayPage()), receiver: this, SLOT(activateDayPage()), Qt::QueuedConnection); |
| 101 | connect(sender: m_journalEditPage, SIGNAL(showDayPage()), receiver: this, SLOT(activateDayPage()), Qt::QueuedConnection); |
| 102 | connect(sender: m_eventOccurrenceEditPage, SIGNAL(showDayPage()), receiver: this, SLOT(activateDayPage()), Qt::QueuedConnection); |
| 103 | connect(sender: m_addCalendarPage, SIGNAL(showPreviousPage()), receiver: this, SLOT(activatePreviousPage()), Qt::QueuedConnection); |
| 104 | connect(sender: m_editCalendarsPage, SIGNAL(showAddCalendarPage(QOrganizerManager*,QOrganizerCollection*)), receiver: this, SLOT(editExistingCalendar(QOrganizerManager*,QOrganizerCollection*)), Qt::QueuedConnection); |
| 105 | connect(sender: m_editCalendarsPage, SIGNAL(showPreviousPage()), receiver: this, SLOT(activateMonthPage()), Qt::QueuedConnection); |
| 106 | connect(sender: m_editCalendarsPage, SIGNAL(addClicked()), receiver: this, SLOT(addCalendar()), Qt::QueuedConnection); |
| 107 | |
| 108 | // Connect to the save and remove request status change signals |
| 109 | connect(sender: &m_saveReq, SIGNAL(stateChanged(QOrganizerAbstractRequest::State)), |
| 110 | receiver: this, SLOT(saveReqStateChanged(QOrganizerAbstractRequest::State))); |
| 111 | connect(sender: &m_remReq, SIGNAL(stateChanged(QOrganizerAbstractRequest::State)), |
| 112 | receiver: this, SLOT(removeReqStateChanged(QOrganizerAbstractRequest::State))); |
| 113 | |
| 114 | m_monthPage->init(); |
| 115 | |
| 116 | m_stackedWidget->addWidget(w: m_monthPage); |
| 117 | m_stackedWidget->addWidget(w: m_dayPage); |
| 118 | m_stackedWidget->addWidget(w: m_eventEditPage); |
| 119 | m_stackedWidget->addWidget(w: m_todoEditPage); |
| 120 | m_stackedWidget->addWidget(w: m_journalEditPage); |
| 121 | m_stackedWidget->addWidget(w: m_eventOccurrenceEditPage); |
| 122 | m_stackedWidget->addWidget(w: m_addCalendarPage); |
| 123 | m_stackedWidget->addWidget(w: m_editCalendarsPage); |
| 124 | m_stackedWidget->setCurrentIndex(0); |
| 125 | |
| 126 | setCentralWidget(m_stackedWidget); |
| 127 | buildMenu(); |
| 128 | |
| 129 | activateMonthPage(); |
| 130 | } |
| 131 | |
| 132 | |
| 133 | |
| 134 | CalendarDemo::~CalendarDemo() |
| 135 | { |
| 136 | |
| 137 | } |
| 138 | |
| 139 | void CalendarDemo::() |
| 140 | { |
| 141 | // Build Options menu |
| 142 | QMenu * = new QMenu("&Options" , this); |
| 143 | menuBar()->addMenu(menu: optionsMenu); |
| 144 | // Add editing options in the menu |
| 145 | QOrganizerManager defaultManager; |
| 146 | QList<QOrganizerItemType::ItemType> supportedItemTypes = defaultManager.supportedItemTypes(); |
| 147 | if (supportedItemTypes.contains(t: QOrganizerItemType::TypeEvent)) { |
| 148 | QAction* addEventAction = optionsMenu->addAction(text: "Add E&vent" ); |
| 149 | connect(sender: addEventAction, SIGNAL(triggered(bool)), receiver: this, SLOT(addNewEvent())); |
| 150 | } |
| 151 | if (supportedItemTypes.contains(t: QOrganizerItemType::TypeTodo)) { |
| 152 | QAction* addTodoAction = optionsMenu->addAction(text: "Add &Todo" ); |
| 153 | connect(sender: addTodoAction, SIGNAL(triggered(bool)), receiver: this, SLOT(addNewTodo())); |
| 154 | } |
| 155 | if (supportedItemTypes.contains(t: QOrganizerItemType::TypeJournal)) { |
| 156 | QAction* addJournalAction = optionsMenu->addAction(text: "Add &Journal" ); |
| 157 | connect(sender: addJournalAction, SIGNAL(triggered(bool)), receiver: this, SLOT(addNewJournal())); |
| 158 | } |
| 159 | optionsMenu->addSeparator(); |
| 160 | QAction* editAction = optionsMenu->addAction(text: "&Edit" ); |
| 161 | connect(sender: editAction, SIGNAL(triggered(bool)), receiver: this, SLOT(editItem())); |
| 162 | QAction* removeAction = optionsMenu->addAction(text: "&Remove" ); |
| 163 | connect(sender: removeAction, SIGNAL(triggered(bool)), receiver: this, SLOT(removeItem())); |
| 164 | optionsMenu->addSeparator(); |
| 165 | m_switchViewAction = optionsMenu->addAction(text: "&Open Day" ); |
| 166 | connect(sender: m_switchViewAction, SIGNAL(triggered(bool)), receiver: this, SLOT(switchView())); |
| 167 | optionsMenu->addSeparator(); |
| 168 | QAction* addHugeEntries = optionsMenu->addAction(text: "Add Test Events" ); |
| 169 | connect(sender: addHugeEntries, SIGNAL(triggered(bool)), receiver: this, SLOT(addEvents())); |
| 170 | QAction* importItems = optionsMenu->addAction(text: "&Import Items..." ); |
| 171 | connect(sender: importItems, SIGNAL(triggered(bool)), receiver: this, SLOT(importItems())); |
| 172 | QAction* exportItems = optionsMenu->addAction(text: "Ex&port Items..." ); |
| 173 | connect(sender: exportItems, SIGNAL(triggered(bool)), receiver: this, SLOT(exportItems())); |
| 174 | QAction* deleteAllEntries = optionsMenu->addAction(text: "Delete All Items" ); |
| 175 | connect(sender: deleteAllEntries, SIGNAL(triggered(bool)), receiver: this, SLOT(deleteAllEntries())); |
| 176 | QAction* addCalendar = optionsMenu->addAction(text: "New calendar" ); |
| 177 | connect(sender: addCalendar, SIGNAL(triggered(bool)), receiver: this, SLOT(addCalendar())); |
| 178 | QAction* editCalendar = optionsMenu->addAction(text: "Edit calendars" ); |
| 179 | connect(sender: editCalendar, SIGNAL(triggered(bool)), receiver: this, SLOT(editCalendar())); |
| 180 | } |
| 181 | |
| 182 | void CalendarDemo::activateMonthPage() |
| 183 | { |
| 184 | menuBar()->setVisible(true); |
| 185 | m_monthPage->refresh(); |
| 186 | m_stackedWidget->setCurrentWidget(m_monthPage); |
| 187 | m_switchViewAction->setText("&Open Day" ); |
| 188 | } |
| 189 | |
| 190 | void CalendarDemo::activateDayPage() |
| 191 | { |
| 192 | menuBar()->setVisible(true); |
| 193 | m_dayPage->refresh(); |
| 194 | m_stackedWidget->setCurrentWidget(m_dayPage); |
| 195 | m_switchViewAction->setText("View &Month" ); |
| 196 | } |
| 197 | |
| 198 | void CalendarDemo::activateEditPage(const QOrganizerItem &item) |
| 199 | { |
| 200 | m_previousItem = item; |
| 201 | menuBar()->setVisible(false); |
| 202 | if (item.type() == QOrganizerItemType::TypeEvent) { |
| 203 | QOrganizerEvent event = static_cast<QOrganizerEvent>(item); |
| 204 | m_dayPage->dayChanged(date: event.startDateTime().date()); // edit always comes back to day page |
| 205 | m_eventEditPage->eventChanged(manager: m_manager, event); |
| 206 | m_stackedWidget->setCurrentWidget(m_eventEditPage); |
| 207 | } else if (item.type() == QOrganizerItemType::TypeTodo) { |
| 208 | QOrganizerTodo todo = static_cast<QOrganizerTodo>(item); |
| 209 | m_dayPage->dayChanged(date: todo.startDateTime().date()); // edit always comes back to day page |
| 210 | m_todoEditPage->todoChanged(manager: m_manager, todo); |
| 211 | m_stackedWidget->setCurrentWidget(m_todoEditPage); |
| 212 | } else if (item.type() == QOrganizerItemType::TypeJournal) { |
| 213 | QOrganizerJournal journal = static_cast<QOrganizerJournal>(item); |
| 214 | m_dayPage->dayChanged(date: journal.dateTime().date()); // edit always comes back to day page |
| 215 | m_journalEditPage->journalChanged(manager: m_manager, journal); |
| 216 | m_stackedWidget->setCurrentWidget(m_journalEditPage); |
| 217 | } else if (item.type() == QOrganizerItemType::TypeEventOccurrence) { |
| 218 | QOrganizerEventOccurrence eventOccurrence = static_cast<QOrganizerEventOccurrence>(item); |
| 219 | QMessageBox msgBox; |
| 220 | msgBox.setText(tr(s: "This is a recurring event" )); |
| 221 | msgBox.setInformativeText(tr(s: "Do you want to open this occurrence or the recurring event series?" )); |
| 222 | QAbstractButton *occurrenceButton = msgBox.addButton(text: tr(s: "Occurrence" ), role: QMessageBox::ActionRole); |
| 223 | QAbstractButton *seriesButton = msgBox.addButton(text: tr(s: "Series" ), role: QMessageBox::ActionRole); |
| 224 | |
| 225 | msgBox.exec(); |
| 226 | if (msgBox.clickedButton() == seriesButton) { |
| 227 | QOrganizerItemId parentEventId = eventOccurrence.parentId(); |
| 228 | QOrganizerEvent parentEvent = m_manager->item(itemId: parentEventId); |
| 229 | m_dayPage->dayChanged(date: parentEvent.startDateTime().date()); // edit always comes back to day page |
| 230 | m_eventEditPage->eventChanged(manager: m_manager, event: parentEvent); |
| 231 | m_stackedWidget->setCurrentWidget(m_eventEditPage); |
| 232 | } else if (msgBox.clickedButton() == occurrenceButton) { |
| 233 | m_dayPage->dayChanged(date: eventOccurrence.startDateTime().date()); // edit always comes back to day page |
| 234 | m_eventOccurrenceEditPage->eventOccurrenceChanged(manager: m_manager, eventOccurrence); |
| 235 | m_stackedWidget->setCurrentWidget(m_eventOccurrenceEditPage); |
| 236 | } |
| 237 | |
| 238 | } |
| 239 | // TODO: |
| 240 | //else if (item.type() == QOrganizerItemType::TypeNote) |
| 241 | } |
| 242 | |
| 243 | void CalendarDemo::activatePreviousPage() |
| 244 | { |
| 245 | if (m_previousPage == m_stackedWidget->indexOf(m_monthPage)) |
| 246 | activateMonthPage(); |
| 247 | else if (m_previousPage == m_stackedWidget->indexOf(m_dayPage)) |
| 248 | activateDayPage(); |
| 249 | else if (m_previousPage == m_stackedWidget->indexOf(m_editCalendarsPage)) |
| 250 | editCalendar(); |
| 251 | else |
| 252 | activateEditPage(item: m_previousItem); |
| 253 | } |
| 254 | |
| 255 | void CalendarDemo::addNewEvent() |
| 256 | { |
| 257 | QOrganizerEvent newEvent; |
| 258 | QDateTime time(m_currentDate); |
| 259 | newEvent.setStartDateTime(time); |
| 260 | time = time.addSecs(secs: 60*30); // add 30 minutes to end time |
| 261 | newEvent.setEndDateTime(time); |
| 262 | activateEditPage(item: newEvent); |
| 263 | } |
| 264 | |
| 265 | void CalendarDemo::addNewTodo() |
| 266 | { |
| 267 | QOrganizerTodo newTodo; |
| 268 | QDateTime time(m_currentDate); |
| 269 | newTodo.setStartDateTime(time); |
| 270 | time = time.addSecs(secs: 60*30); // add 30 minutes to due time |
| 271 | newTodo.setDueDateTime(time); |
| 272 | activateEditPage(item: newTodo); |
| 273 | } |
| 274 | |
| 275 | void CalendarDemo::addNewJournal() |
| 276 | { |
| 277 | QOrganizerJournal newJournal; |
| 278 | QDateTime time(m_currentDate); |
| 279 | newJournal.setDateTime(time); |
| 280 | activateEditPage(item: newJournal); |
| 281 | } |
| 282 | |
| 283 | void CalendarDemo::switchView() |
| 284 | { |
| 285 | if (m_stackedWidget->currentWidget() == m_dayPage) { |
| 286 | activateMonthPage(); |
| 287 | } else if (m_stackedWidget->currentWidget() == m_monthPage) { |
| 288 | activateDayPage(); |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | void CalendarDemo::editItem() |
| 293 | { |
| 294 | if (m_stackedWidget->currentWidget() == m_dayPage) { |
| 295 | m_dayPage->editItem(); |
| 296 | } else if (m_stackedWidget->currentWidget() == m_monthPage) { |
| 297 | m_monthPage->editItem(); |
| 298 | } |
| 299 | } |
| 300 | |
| 301 | void CalendarDemo::removeItem() |
| 302 | { |
| 303 | if (m_stackedWidget->currentWidget() == m_dayPage) { |
| 304 | m_dayPage->removeItem(); |
| 305 | } else if (m_stackedWidget->currentWidget() == m_monthPage) { |
| 306 | m_monthPage->removeItem(); |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | void CalendarDemo::addEvents() |
| 311 | { |
| 312 | QList<QOrganizerItem> items; |
| 313 | |
| 314 | // Create a large number of events asynchronously |
| 315 | QOrganizerCollectionId defaultCollectionId = m_manager->defaultCollectionId(); |
| 316 | for(int index=0 ; index < 100 ; index++) { |
| 317 | QOrganizerItem item; |
| 318 | item.setType(QOrganizerItemType::TypeEvent); |
| 319 | item.setDescription(QString("Event %1" ).arg(a: index)); |
| 320 | item.setDisplayLabel(QString("Subject for event %1" ).arg(a: index + 1)); |
| 321 | |
| 322 | // Set the start date to index to add events to next 5000 days |
| 323 | QOrganizerEventTime timeRange; |
| 324 | timeRange.setStartDateTime(QDateTime::currentDateTime().addDays(days: index)); |
| 325 | timeRange.setEndDateTime(QDateTime::currentDateTime().addDays(days: index).addSecs(secs: 60 * 60)); |
| 326 | item.saveDetail(detail: &timeRange); |
| 327 | |
| 328 | item.setCollectionId(defaultCollectionId); |
| 329 | |
| 330 | items.append(t: item); |
| 331 | } |
| 332 | |
| 333 | // Now create a save request and execute it |
| 334 | m_saveReq.setItems(items); |
| 335 | m_saveReq.setManager(m_manager); |
| 336 | m_saveReq.start(); |
| 337 | } |
| 338 | |
| 339 | void CalendarDemo::importItems() |
| 340 | { |
| 341 | #ifdef BUILD_VERSIT |
| 342 | QString messageTitle(tr("Import of Items failed" )); |
| 343 | if (!m_manager) { |
| 344 | QMessageBox::warning(this, messageTitle, tr("No manager selected; cannot import" )); |
| 345 | return; |
| 346 | } |
| 347 | QString docPath = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); |
| 348 | if (docPath.isEmpty()) |
| 349 | docPath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); |
| 350 | if (docPath.isEmpty()) |
| 351 | docPath = "." ; |
| 352 | QString fileName = QFileDialog::getOpenFileName(this, |
| 353 | tr("Select iCalendar file" ), docPath, tr("iCalendar files (*.ics)" )); |
| 354 | |
| 355 | // user chose to cancel file dialog? |
| 356 | if (fileName.isEmpty()) |
| 357 | return; |
| 358 | |
| 359 | QFile file(fileName); |
| 360 | if (!file.open(QIODevice::ReadOnly) || !file.isReadable()){ |
| 361 | QMessageBox::warning(this, messageTitle, tr("Unable to read from file: %1" ).arg(fileName)); |
| 362 | return; |
| 363 | } |
| 364 | QVersitReader reader; |
| 365 | reader.setDevice(&file); |
| 366 | if (!reader.startReading() || !reader.waitForFinished()) { |
| 367 | QMessageBox::warning(this, messageTitle, tr("Versit reader failed: %1" ).arg(reader.error())); |
| 368 | return; |
| 369 | } |
| 370 | QVersitOrganizerImporter importer; |
| 371 | QList<QOrganizerItem> allItems; |
| 372 | QString errorMessage; |
| 373 | foreach (const QVersitDocument& document, reader.results()) { |
| 374 | if (!importer.importDocument(document)) { |
| 375 | errorMessage += tr("Import failed," ); |
| 376 | QMap<int, QVersitOrganizerImporter::Error>::const_iterator iterator = importer.errorMap().constBegin(); |
| 377 | while(iterator != importer.errorMap().constEnd()){ |
| 378 | switch (iterator.value()){ |
| 379 | case QVersitOrganizerImporter::InvalidDocumentError: |
| 380 | errorMessage += QString(" index %1:" ).arg(iterator.key()); |
| 381 | errorMessage += tr("One of the documents is not an iCalendar file" ); |
| 382 | break; |
| 383 | case QVersitOrganizerImporter::EmptyDocumentError: |
| 384 | errorMessage += QString(" index %1:" ).arg(iterator.key()); |
| 385 | errorMessage += tr("One of the documents is empty" ); |
| 386 | break; |
| 387 | default: |
| 388 | errorMessage += QString(" index %1:" ).arg(iterator.key()); |
| 389 | errorMessage += tr("Unknown error" ); |
| 390 | } |
| 391 | ++iterator; |
| 392 | } |
| 393 | errorMessage += QLatin1String("\n" ); |
| 394 | continue; |
| 395 | } |
| 396 | QList<QOrganizerItem> items = importer.items(); |
| 397 | foreach (const QOrganizerItem& item, items) { |
| 398 | allItems.append(item); |
| 399 | } |
| 400 | } |
| 401 | if (!errorMessage.isEmpty()) |
| 402 | QMessageBox::warning(this, messageTitle, errorMessage); |
| 403 | |
| 404 | m_manager->saveItems(&allItems); |
| 405 | m_monthPage->refresh(); |
| 406 | m_dayPage->refresh(); |
| 407 | #endif |
| 408 | } |
| 409 | |
| 410 | void CalendarDemo::exportItems() |
| 411 | { |
| 412 | #ifdef BUILD_VERSIT |
| 413 | QString messageTitle(tr("Export of Items failed" )); |
| 414 | if (!m_manager) { |
| 415 | QMessageBox::warning(this, messageTitle, tr("No manager selected; cannot export" )); |
| 416 | return; |
| 417 | } |
| 418 | QString docPath = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); |
| 419 | if (docPath.isEmpty()) |
| 420 | docPath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); |
| 421 | if (docPath.isEmpty()) |
| 422 | docPath = "." ; |
| 423 | docPath.append("/calendar.ics" ); |
| 424 | QString fileName = QFileDialog::getSaveFileName(this, tr("Save iCalendar" ), |
| 425 | docPath, |
| 426 | tr("iCalendar files (*.ics)" )); |
| 427 | // user chose to cancel file dialog? |
| 428 | if (fileName.isEmpty()) |
| 429 | return; |
| 430 | |
| 431 | QFile file(fileName); |
| 432 | if (!file.open(QIODevice::WriteOnly) || !file.isWritable()) { |
| 433 | QMessageBox::warning(this, messageTitle, tr("Unable to write to file: %1" ).arg(fileName)); |
| 434 | return; |
| 435 | } |
| 436 | QList<QOrganizerItem> items(m_manager->itemsForExport()); |
| 437 | QVersitOrganizerExporter exporter; |
| 438 | QString errorMessage; |
| 439 | if (!exporter.exportItems(items)) { |
| 440 | errorMessage += tr("Export failed," ); |
| 441 | QMap<int, QVersitOrganizerExporter::Error>::const_iterator iterator = exporter.errorMap().constBegin(); |
| 442 | while(iterator != exporter.errorMap().constEnd()){ |
| 443 | switch (iterator.value()){ |
| 444 | case QVersitOrganizerExporter::EmptyOrganizerError: |
| 445 | errorMessage += QString(" index %1:" ).arg(iterator.key()); |
| 446 | errorMessage += tr("One of the documents is not an iCalendar file" ); |
| 447 | break; |
| 448 | case QVersitOrganizerExporter::UnknownComponentTypeError: |
| 449 | errorMessage += QString(" index %1:" ).arg(iterator.key()); |
| 450 | errorMessage += tr("One of the components in the iCalendar file is" |
| 451 | " not supported" ); |
| 452 | break; |
| 453 | case QVersitOrganizerExporter::UnderspecifiedOccurrenceError: |
| 454 | errorMessage += QString(" index %1:" ).arg(iterator.key()); |
| 455 | errorMessage += tr("An event or todo exception was found which" |
| 456 | " did not specify both its parent and a specifier for" |
| 457 | " which instance to override" ); |
| 458 | break; |
| 459 | default: |
| 460 | errorMessage += QString(" index %1:%2 " ).arg(iterator.key()) |
| 461 | .arg(tr("Unknown error" )); |
| 462 | } |
| 463 | ++iterator; |
| 464 | } |
| 465 | errorMessage += QLatin1String("\n" ); |
| 466 | if (!errorMessage.isEmpty()){ |
| 467 | QMessageBox::warning(this, messageTitle, errorMessage); |
| 468 | return; |
| 469 | } |
| 470 | } |
| 471 | QVersitDocument document = exporter.document(); |
| 472 | QVersitWriter writer; |
| 473 | writer.setDevice(&file); |
| 474 | if (!writer.startWriting(QList<QVersitDocument>() << document) |
| 475 | || !writer.waitForFinished()) { |
| 476 | QMessageBox::warning(this, messageTitle, |
| 477 | tr("Versit writing of organizer items failed: %1" ).arg(writer.error())); |
| 478 | } |
| 479 | #endif |
| 480 | } |
| 481 | |
| 482 | void CalendarDemo::deleteAllEntries() |
| 483 | { |
| 484 | // Fetch all the entries |
| 485 | QList<QOrganizerItemId> ids = m_manager->itemIds(); |
| 486 | |
| 487 | if(ids.count()) { |
| 488 | m_remReq.setItemIds(ids); |
| 489 | m_remReq.setManager(m_manager); |
| 490 | m_remReq.start(); |
| 491 | } |
| 492 | } |
| 493 | |
| 494 | void CalendarDemo::addCalendar() |
| 495 | { |
| 496 | // Get default collection |
| 497 | QOrganizerCollection defaultCollection = m_manager->collection(collectionId: m_manager->defaultCollectionId()); |
| 498 | |
| 499 | QOrganizerCollection newCollection = defaultCollection; |
| 500 | newCollection.setId(QOrganizerCollectionId()); // reset collection id |
| 501 | m_addCalendarPage->calendarChanged(manager: m_manager, calendar&: newCollection); |
| 502 | |
| 503 | m_previousPage = m_stackedWidget->currentIndex(); |
| 504 | m_stackedWidget->setCurrentWidget(m_addCalendarPage); |
| 505 | } |
| 506 | |
| 507 | void CalendarDemo::editCalendar() |
| 508 | { |
| 509 | m_editCalendarsPage->showPage(manager: m_manager); |
| 510 | m_previousPage = m_stackedWidget->currentIndex(); |
| 511 | m_stackedWidget->setCurrentWidget(m_editCalendarsPage); |
| 512 | } |
| 513 | |
| 514 | void CalendarDemo::editExistingCalendar(QOrganizerManager *manager, QOrganizerCollection* calendar) |
| 515 | { |
| 516 | m_addCalendarPage->calendarChanged(manager, calendar&: *calendar); |
| 517 | m_previousPage = m_stackedWidget->currentIndex(); |
| 518 | m_stackedWidget->setCurrentWidget(m_addCalendarPage); |
| 519 | } |
| 520 | |
| 521 | void CalendarDemo::saveReqStateChanged(QOrganizerAbstractRequest::State reqState) |
| 522 | { |
| 523 | if(QOrganizerAbstractRequest::ActiveState == reqState) { |
| 524 | // Request started. Show a progress or wait dialog |
| 525 | m_progressDlg = new QProgressDialog("Saving events.." , "Cancel" , 100, 100, this); |
| 526 | connect(sender: m_progressDlg, SIGNAL(canceled()), receiver: &m_saveReq, SLOT(cancel())); |
| 527 | m_progressDlg->show(); |
| 528 | } else if (QOrganizerAbstractRequest::FinishedState == reqState || |
| 529 | QOrganizerAbstractRequest::CanceledState == reqState) { |
| 530 | // Request finished or cancelled. Stop showing the progress dialog and refresh |
| 531 | m_progressDlg->hide(); |
| 532 | m_monthPage->refresh(); |
| 533 | m_dayPage->refresh(); |
| 534 | } |
| 535 | } |
| 536 | |
| 537 | void CalendarDemo::removeReqStateChanged(QOrganizerAbstractRequest::State reqState) |
| 538 | { |
| 539 | if(QOrganizerAbstractRequest::ActiveState == reqState) { |
| 540 | // Request started. Show a progress or wait dialog |
| 541 | m_progressDlg = new QProgressDialog("Removing events.." , "Cancel" , 100, 100, this); |
| 542 | connect(sender: m_progressDlg, SIGNAL(canceled()), receiver: &m_remReq, SLOT(cancel())); |
| 543 | m_progressDlg->show(); |
| 544 | } else if (QOrganizerAbstractRequest::FinishedState == reqState || |
| 545 | QOrganizerAbstractRequest::CanceledState == reqState) { |
| 546 | // Request finished or cancelled. Stop showing the progress dialog and refresh |
| 547 | m_progressDlg->hide(); |
| 548 | m_monthPage->refresh(); |
| 549 | m_dayPage->refresh(); |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | void CalendarDemo::changeManager(QOrganizerManager *manager) |
| 554 | { |
| 555 | m_manager = manager; |
| 556 | } |
| 557 | |
| 558 | void CalendarDemo::updateSelectedDay(const QDate& date) |
| 559 | { |
| 560 | m_dayPage->dayChanged(date); |
| 561 | m_currentDate = date; |
| 562 | } |
| 563 | |