- Qt 5.0
- ToDo Example
- Qt 5.0.0 Reference Documentation

# ToDo Example

     /****************************************************************************
     **
     ** Copyright (C) 2020 The Qt Company Ltd.
     ** Contact: https://www.qt.io/licensing/
     **
     ** This file is part of the examples for the Qt PIM module of the Qt Toolkit.
     **
     ** $QT_BEGIN_LICENSE:BSD$
     ** Commercial License Usage
     ** Licensees holding valid commercial Qt licenses may use this file in
     ** accordance with the commercial license agreement provided with the
     ** Software or, alternatively, in accordance with the terms contained in
     ** a written agreement between you and The Qt Company. For licensing terms
     ** and conditions see https://www.qt.io/terms-conditions. For further
     ** information use the contact form at https://www.qt.io/contact-us.
     **
     ** BSD License Usage
     ** Alternatively, 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 The Qt Company Ltd 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 <QtWidgets>

     #include <QtOrganizer/qorganizer.h>

     #include "window.h"
     #include "todoeditor.h"

     QTORGANIZER_USE_NAMESPACE

     Window::Window()
     {
         setupGui();

         manager = new QOrganizerManager("memory");

         setWindowTitle(tr("ToDo Example"));
         refreshList();
     }

     Window::~Window()
     {
         delete manager;
     }

     void Window::editNewTodo()
     {
         QOrganizerTodo newTodo;
         newTodo.setPriority(QOrganizerItemPriority::HighPriority);
         newTodo.setStatus(QOrganizerTodoProgress::StatusNotStarted);
         QDateTime currentDateTime(calendarWidget->selectedDate(),
             QTime::currentTime());
         newTodo.setStartDateTime(currentDateTime);
         newTodo.setDueDateTime(currentDateTime.addSecs(60*60));

         todoEditor->editTodo(newTodo);

         stackedWidget->setCurrentWidget(todoEditor);
     }

     Q_DECLARE_METATYPE(QOrganizerTodo)

     void Window::editTodo(QListWidgetItem *item)
     {
         QVariant variant = item->data(Qt::UserRole);
         if (!variant.canConvert<QOrganizerTodo>())
             return;

         QOrganizerTodo todo = variant.value<QOrganizerTodo>();
         todoEditor->editTodo(todo);
         stackedWidget->setCurrentWidget(todoEditor);
     }

     void Window::saveTodo(QOrganizerTodo &todo)
     {
         manager->saveItem(&todo);

         stackedWidget->setCurrentIndex(0);
         refreshList();
     }

     void Window::deleteTodo()
     {
         QList<QListWidgetItem *> items = listWidget->selectedItems();
         if (!items.isEmpty()) {
             QVariant variant = items.at(0)->data(Qt::UserRole);
             if (variant.canConvert<QOrganizerTodo>()) {
                 QOrganizerTodo theTodo = variant.value<QOrganizerTodo>();
                 manager->removeItem(theTodo.id());
                 refreshList();
             }
         }
     }

     void Window::refreshList()
     {
         listWidget->clear();

         QOrganizerItemSortOrder sortOrder;
         sortOrder.setDetail(QOrganizerItemDetail::TypeTodoTime, QOrganizerTodoTime::FieldDueDateTime);

         QList<QOrganizerItem> items =
                 manager->items(QDateTime(), QDateTime(), QOrganizerItemFilter(), -1, QList<QOrganizerItemSortOrder>() << sortOrder);
         if (items.isEmpty()) {
            new QListWidgetItem("<No Todos>", listWidget);
         }
         foreach(QOrganizerItem item, items) {
             if (item.type() == QOrganizerItemType::TypeTodo) {
                 QOrganizerTodo todo = static_cast<QOrganizerTodo>(item);
                 if (todo.startDateTime() > calendarWidget->selectedDate().endOfDay() ||
                     todo.dueDateTime() < calendarWidget->selectedDate().startOfDay())
                     continue;

                 QString display = todo.startDateTime().toString("yy/MM/dd hh:mm") +
                     "-" + todo.dueDateTime().toString("yy/MM/dd hh:mm") +
                     " - "+ todo.displayLabel();

                 QListWidgetItem *listItem =
                     new QListWidgetItem(display, listWidget);
                 listItem->setData(Qt::UserRole, QVariant::fromValue(todo));
             }
         }
     }

     void Window::setupGui()
     {
         todoEditor = new TodoEditor;

         listWidget = new QListWidget;
         stackedWidget = new QStackedWidget;
         newTodoButton = new QPushButton(tr("New Todo"));
         deletTodoButton = new QPushButton(tr("Delete Todo"));
         calendarWidget = new QCalendarWidget;

         connect(newTodoButton, SIGNAL(clicked()), this, SLOT(editNewTodo()));
         connect(todoEditor, SIGNAL(editingFinished(QOrganizerTodo &)),
                 this, SLOT(saveTodo(QOrganizerTodo &)));
         connect(listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
                 this, SLOT(editTodo(QListWidgetItem*)));
         connect(calendarWidget, SIGNAL(selectionChanged()),
                 this, SLOT(refreshList()));
         connect(deletTodoButton, SIGNAL(clicked()), this, SLOT(deleteTodo()));

         QVBoxLayout *mainLayout = new QVBoxLayout;
         mainLayout->addWidget(calendarWidget);
         mainLayout->addWidget(listWidget);

         QHBoxLayout *buttonLayout = new QHBoxLayout;
         buttonLayout->addWidget(newTodoButton);
         buttonLayout->addWidget(deletTodoButton);
         mainLayout->addLayout(buttonLayout);

         QWidget *frontPage = new QWidget;
         frontPage->setLayout(mainLayout);

         stackedWidget->addWidget(frontPage);
         stackedWidget->addWidget(todoEditor);

         // Adding a scroll area to allow proper rendering of the UI on small screens
         QScrollArea *scrollArea = new QScrollArea;
         scrollArea->setWidgetResizable(true);
         scrollArea->setWidget(stackedWidget);
         QSize suggestedSize;
         suggestedSize = stackedWidget->sizeHint();
         stackedWidget->setMinimumSize(suggestedSize);

         QGridLayout *layout = new QGridLayout;
         layout->addWidget(scrollArea);

         setLayout(layout);
     }