File indexing completed on 2025-01-05 04:59:45

0001 /*
0002  * SPDX-FileCopyrightText: 2015 Theo Vaucher <theo.vaucher@gmail.com>
0003  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004  */
0005 
0006 
0007 #include "workdaypagemodel.h"
0008 
0009 #include <QMimeData>
0010 
0011 #include <KLocalizedString>
0012 
0013 
0014 #include "presentation/querytreemodel.h"
0015 
0016 #include "utils/datetime.h"
0017 
0018 using namespace Presentation;
0019 
0020 WorkdayPageModel::WorkdayPageModel(const Domain::TaskQueries::Ptr &taskQueries,
0021                                    const Domain::TaskRepository::Ptr &taskRepository,
0022                                    QObject *parent)
0023     : PageModel(parent),
0024       m_taskQueries(taskQueries),
0025       m_taskRepository(taskRepository)
0026 {
0027 }
0028 
0029 Domain::Task::Ptr WorkdayPageModel::addItem(const QString &title, const QModelIndex &parentIndex)
0030 {
0031     const auto parentData = parentIndex.data(QueryTreeModelBase::ObjectRole);
0032     const auto parentTask = parentData.value<Domain::Task::Ptr>();
0033 
0034     auto task = Domain::Task::Ptr::create();
0035     task->setTitle(title);
0036     if (!parentTask)
0037         task->setStartDate(Utils::DateTime::currentDate());
0038     const auto job = parentTask ? m_taskRepository->createChild(task, parentTask)
0039                    : m_taskRepository->create(task);
0040     installHandler(job, i18n("Cannot add task %1 in Workday", title));
0041 
0042     return task;
0043 }
0044 
0045 void WorkdayPageModel::removeItem(const QModelIndex &index)
0046 {
0047     QVariant data = index.data(QueryTreeModelBase::ObjectRole);
0048     auto task = data.value<Domain::Task::Ptr>();
0049     if (task) {
0050         const auto job = m_taskRepository->remove(task);
0051         installHandler(job, i18n("Cannot remove task %1 from Workday", task->title()));
0052     }
0053 }
0054 
0055 void WorkdayPageModel::promoteItem(const QModelIndex &index)
0056 {
0057     QVariant data = index.data(QueryTreeModelBase::ObjectRole);
0058     auto task = data.value<Domain::Task::Ptr>();
0059     Q_ASSERT(task);
0060     const auto job = m_taskRepository->promoteToProject(task);
0061     installHandler(job, i18n("Cannot promote task %1 to be a project", task->title()));
0062 }
0063 
0064 QAbstractItemModel *WorkdayPageModel::createCentralListModel()
0065 {
0066     auto query = [this](const Domain::Task::Ptr &task) -> Domain::QueryResultInterface<Domain::Task::Ptr>::Ptr {
0067         if (!task)
0068             return m_taskQueries->findWorkdayTopLevel();
0069         else
0070             return m_taskQueries->findChildren(task);
0071     };
0072 
0073     auto flags = [](const Domain::Task::Ptr &task) {
0074         const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable
0075                                          | Qt::ItemIsEnabled
0076                                          | Qt::ItemIsEditable
0077                                          | Qt::ItemIsDragEnabled;
0078 
0079         return task ? (defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled) : defaultFlags;
0080     };
0081 
0082     auto data = [](const Domain::Task::Ptr &task, int role, const TaskExtraDataPtr &info) {
0083         return defaultTaskData(task, role, info);
0084     };
0085 
0086     auto fetchAdditionalInfo = [this](const QModelIndex &index, const Domain::Task::Ptr &task) {
0087         return fetchTaskExtraData(m_taskQueries, TaskExtraPart::Project, index, task);
0088     };
0089 
0090     auto setData = [this](const Domain::Task::Ptr &task, const QVariant &value, int role) {
0091         if (role != Qt::EditRole && role != Qt::CheckStateRole) {
0092             return false;
0093         }
0094 
0095         const auto currentTitle = task->title();
0096         if (role == Qt::EditRole)
0097             task->setTitle(value.toString());
0098         else
0099             task->setDone(value.toInt() == Qt::Checked);
0100 
0101         const auto job = m_taskRepository->update(task);
0102         installHandler(job, i18n("Cannot modify task %1 in Workday", currentTitle));
0103         return true;
0104     };
0105 
0106     auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const Domain::Task::Ptr &parentTask) {
0107         if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object")))
0108             return false;
0109 
0110         auto droppedTasks = mimeData->property("objects").value<Domain::Task::List>();
0111         if (droppedTasks.isEmpty())
0112             return false;
0113 
0114         foreach(const auto &childTask, droppedTasks) {
0115             if (parentTask) {
0116                 const auto job = m_taskRepository->associate(parentTask, childTask);
0117                 installHandler(job, i18n("Cannot move task %1 as sub-task of %2", childTask->title(), parentTask->title()));
0118             } else {
0119                 childTask->setStartDate(Utils::DateTime::currentDate());
0120                 // TODO something like m_taskRepository->update(childTask) is missing here
0121                 // It was removed in commit c97a99bf because it led to a LLCONFLICT in akonadi (due to dissociate below).
0122                 // The removal broke tests-features-workday-workdaydraganddropfeature (date not changed).
0123 
0124                 auto job = m_taskRepository->dissociate(childTask);
0125                 installHandler(job, i18n("Cannot deparent task %1 from its parent", childTask->title()));
0126             }
0127         }
0128 
0129         return true;
0130     };
0131 
0132     auto drag = [](const Domain::Task::List &tasks) -> QMimeData* {
0133         if (tasks.isEmpty())
0134             return nullptr;
0135 
0136         auto data = new QMimeData;
0137         data->setData(QStringLiteral("application/x-zanshin-object"), "object");
0138         data->setProperty("objects", QVariant::fromValue(tasks));
0139         return data;
0140     };
0141 
0142     return new QueryTreeModel<Domain::Task::Ptr, TaskExtraDataPtr>(query, flags, data, setData, drop, drag, fetchAdditionalInfo, this);
0143 }
0144 
0145 #include "moc_workdaypagemodel.cpp"