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 | |