/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt PIM Module.
**
** $QT_BEGIN_LICENSE:FDL$
** 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.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \example todo
    \title ToDo Example

    The ToDo example shows how to organize todo items using the
    Qt Organizer framework.

    \image todoexample.png

    Most organizing software, e.g., calendar applications, lets the
    user create todo items, which describe an activity that should be
    completed. Other items may include meetings, notes, and events. A
    todo item typically includes the following information:

    \list
        \li A timestamp for when the item was created.
        \li A timestamp for when the activity should be completed.
        \li A timestamp for when the activity was completed.
        \li A priority for how important the activity is.
        \li Information on whether the todo is recurring (i.e.,
           if it should be repeated at regular intervals).
        \li A description of the activity.
    \endlist

    A todo item is represented in Qt with the QOrganizerTodo class.
    Instances are managed by a QOrganizerManager, which can save
    todos created by a program and return the todo items it manages.
    QOrganizerTodo contains the information mentioned in the list
    above. In Qt, we call this item details. They are represented by
    QOrganizerItemDetail and its subclasses. For instance,
    QOrganizerTodo keeps a QOrganizerItemPriority (which inherits
    QOrganizerItemDetail).

    The item details available for a QOrganizerTodo follows a
    standardized schema, i.e, a todo item has a standard set of item
    details. Most \l{QOrganizerManager} backends will follow this
    schema. A backend is the implementation of the
    \l{QOrganizerManager}'s functionality for a specific platform.
    Some backends may not support all details, and possibly include
    others.

    The example consists of two classes:

    \list
        \li \c Window: Lets the user select a date and create todo
            items for the date selected. It also displays a list
            with todo items for the date selected.
        \li \c TodoEditor: Lets the user edit a todo item using
            standard Qt widgets.
    \endlist

    We will now look at the definitions and implementations of \c
    Window and \c TodoEditor.

    \section1 Window Class Definition

    The \c Window class is responsible for setting up the GUI of
    the example. It creates QOrganizerTodo items and send them to
    the TodoEditor for editing. It saves and retrieves todo items
    from the organizer item manager.

    Let's take a look at its definition.

    \snippet examples/todo/window.h 0

    The slots are connected to the widgets of \c Window, and handles
    user requests to create a new todo item, edit an existing item,
    and delete an item. The \c saveTodo() slot is invoked when the
    user has finished editing a todo item. \c refreshList() updates
    the \gui {Todo Item List} when todo items are added, deleted, or
    edited.

    We'll now go through the slots and constructor of \c Window. The
    only other function, \c setupGui(), initializes and lays out the
    widgets, and that is treated in other examples.

    \section1 Window Class Implementation

    The constructor creates the QOrganizerManager instance:

    \snippet examples/todo/window.cpp 0

    We here instruct that the manger should use the \c memory backend.
    This backend implements the default schema and uses the computers
    memory for storing items. This way, we can be sure that the
    backend will behave equally on all platforms.

    The \c editNewTodo() slot is connected to the \gui {New Todo
    Button}, and sets up a new QOrganizerTodo for editing.

    \snippet examples/todo/window.cpp 1

    Here we set the item details of the new QOrganizerTodo to
    reasonable defaults. The \c editTodo() slot sets up the widgets of
    the \c TodoEditor with the data from the new todo. Finally, the
    stacked widget is set to show the todo editor.

    The \c editTodo() slot is invoked when the player double clicks a
    todo item in the \gui { Todo Item List } with the mouse.

    \snippet examples/todo/window.cpp 2

    \omit Should I mention item view roles as well? \endomit

    The slot is invoked with the QListWidgetItem that was double
    clicked. We have saved the QOrganizerTodo in the list widget item.
    The list widget item stores data in \l{QVariant}s, so we need to
    include the Q_DECLARE_METATYPE() macro, which helps make
    \l{QOrganizerTodo}s usable with QVariant.

    When we have retrieved the todo item, we send it to the \c
    TodoEditor for editing, which we show on the screen.

    The \c saveTodo() slot is invoked by the \c TodoEditor when the
    user has finished editing.

    \snippet examples/todo/window.cpp 3

    Saving a QOrganizerTodo in the QOrganizerManager is easy using
    the \l{QOrganizerManager::}{saveItem()} function. We call the
    \c refreshList() slot to update the \gui { Todo Item List } so
    that new and edited todos is displayed correctly.

    The \c deleteTodo() slot is connected to the \gui {Delete Todo
    Button}, and will delete the currently selected todo in the
    \gui { Todo List } from the manager.

    \snippet examples/todo/window.cpp 4

    Here we fetch the selected list widget item from the list. To
    delete the item in the manager, we send the items
    \l{QOrganizerItem::id()}{id} to the manager's
    \l{QOrganizerManager::}{removeItem()} function. An item's
    id uniquely identifies it in its manager.

    We now move on to the \c refreshList() function, which set's up
    the \gui { Todo List } with the todo items currently stored in the
    manager.

    \snippet examples/todo/window.cpp 5

    First we remove all items from the list widget, i.e., we set
    up the list from scratch each time \c refreshList() is called.

    The \l{QOrganizerManager::}{items()} functions retrieves
    \l{QOrganizerItem}s from the manager. By giving the manager a
    QOrganizerItemSortOrder, the manager will sort the items for us.
    The sort order takes the item detail it should sort after.  You
    also need to specify which field of the detail should be used for
    sorting. Note that all details have a DefinitionName constant
    declared. They also keep constants for all of their fields. The
    \l{QOrganizerManager::}{items()} takes a list of sort orders
    in case one wants to sort by more than one field.

    It is also possible to let the manager filter items. You can
    look up the QOrganizerItemFilter class description for
    details.

    \snippet examples/todo/window.cpp 6

    We iterate through the todo items in the manager, keeping the
    items that are active, i.e., the date selected in the calendar is
    between the start and due dates of the item.

    We create a list widget item for the todo. We set its text to the
    item's start sate, due date, and
    \l{QOrganizerItem::}{displayLabel()}.

    We save the QOrganizerTodo itself in the Qt::UserRole of the list
    widget item. We have seen previously how to retrieve it.

    \section1 TodoEditor Class Definition

    The \c TodoEditor contains widgets for editing a
    QOrganizerTodo.

    \image todoeditor.png

    Here is the \c TodoEditor class's definition:

    \snippet examples/todo/todoeditor.h 0

    The \c editTodo() slot is called by \c Window when a todo item
    should be edited. \c finishEditing() is connected to \c
    doneButton, and emits the \c editingFinished() signal. This signal
    is connected to the \c saveTodo() slot of the \c Window.

    The rest of slots are connected to the widgets that edit the todo
    item's details.

    \c setupGui() creates, lays out, and connects the widgets to the
    slots of \c TodoEditor. \c setupCombos() helps \c setupGui() by
    creating the comboboxes and by filling their drop-down lists.

    \section1 TodoEditor Class Implementation

    We start by taking a quick look at \c setupCombos(), which sets
    up the \l{QComboBox}es.

    \snippet examples/todo/todoeditor.cpp 0

    As with list widget items, you can also store user data in an item
    of QComboBox's drop-down list. Here we save a \l{QOrganizerTodo}'s
    possible values for its \l{QOrganizerTodo::}{priority()} and
    \l{QOrganizerTodo::}{status()} details. The \c alarmCombo helps
    the user select a time for when to be reminded of the todo.

    The \c editTodo() slot is called when a new QOrganizerTodo should
    be edited.

    \snippet examples/todo/todoeditor.cpp 1

    We set the contents of our widgets to the details of the todo
    item. The functions we use here are utility functions provided by
    QOrganizerTodo that accesses the \l{QOrganizerItemDetail}s for us.
    We could also have accessed them by using the
    \l{QOrganizerItemDetail::}{value()} functions of
    QOrganizerItemDetail.

    \snippet examples/todo/todoeditor.cpp 2

    Many backends support notifying the user when a todo item is due.
    We can request this by adding a QOrganizerItemRemainder detail to
    the QOrganizerTodo. We first check whether a remainder detail is
    present on the todo item. If it is we update the \gui {Alarm Combo
    Box}. The \l{QDateTime::}{secsTo()} function returns the
    difference between two \l{QDateTime}s in seconds.

    The next two slots update the subject and description of the
    todo item.

    \snippet examples/todo/todoeditor.cpp 3

    We save the subject in the item's
    \l{QOrganizerItem::}{displayLabel()}, which is meant for
    displaying a short description that can be used in item views.
    The \l{QOrganizerItem::}{description()} is a longer text
    describing the item.

    The \c updateDates() slot is connected to the two
    \l{QDateTimeEdit}s that let the user select start and due dates
    for the todo item.

    \snippet examples/todo/todoeditor.cpp 4

    Note that we need to update the remainder detail when the due date
    changes because the remainder is calculated relative to the due
    date. We do that in \c updateAlarm(), which we will come back to
    later.

    The \c updateStatus() and \c updatePriority() functions are
    connected to the combo boxes that we created in \c
    setupCombos().

    \snippet examples/todo/todoeditor.cpp 5

    The only thing to notice here is that enum values are saved as \c
    {int}s in the drop-down list items.

    The \c updateAlarm() function is connected to the \c
    alarmCombo as we saw earlier.

    \snippet examples/todo/todoeditor.cpp 6

    We first calculate the time before the todo is due the
    alarm should go off. We calculate this in seconds because
    \l{QDateTime}'s \l{QDateTime::}{addSecs()} function gives us
    an easy way of finding the time from the todo's due time.

    Before we add the new reminder, we need to remove any previously
    added reminders; if not, the QOrganizerTodo item would have
    several \l{QOrganizerItemVisualReminder}s registered with it.

    The reminder is not accessible through the convenience
    functions of QOrganizerTodo, so we add it using the item
    detail access functions from QOrganizerItem.
*/

