File indexing completed on 2024-06-02 05:33:01

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org>
0003  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004  */
0005 
0006 
0007 #include "projectpagemodel.h"
0008 
0009 #include <QMimeData>
0010 
0011 #include <KLocalizedString>
0012 
0013 #include "presentation/querytreemodel.h"
0014 
0015 using namespace Presentation;
0016 
0017 ProjectPageModel::ProjectPageModel(const Domain::Project::Ptr &project,
0018                                    const Domain::ProjectQueries::Ptr &projectQueries,
0019                                    const Domain::ProjectRepository::Ptr &projectRepository,
0020                                    const Domain::TaskQueries::Ptr &taskQueries,
0021                                    const Domain::TaskRepository::Ptr &taskRepository,
0022                                    QObject *parent)
0023     : PageModel(parent),
0024       m_projectQueries(projectQueries),
0025       m_projectRepository(projectRepository),
0026       m_project(project),
0027       m_taskQueries(taskQueries),
0028       m_taskRepository(taskRepository)
0029 {
0030 }
0031 
0032 Domain::Project::Ptr ProjectPageModel::project() const
0033 {
0034     return m_project;
0035 }
0036 
0037 Domain::Task::Ptr ProjectPageModel::addItem(const QString &title, const QModelIndex &parentIndex)
0038 {
0039     const auto parentData = parentIndex.data(QueryTreeModelBase::ObjectRole);
0040     const auto parentTask = parentData.value<Domain::Task::Ptr>();
0041 
0042     auto task = Domain::Task::Ptr::create();
0043     task->setTitle(title);
0044 
0045     const auto job = parentTask ? m_taskRepository->createChild(task, parentTask)
0046                    : m_taskRepository->createInProject(task, m_project);
0047     installHandler(job, i18n("Cannot add task %1 in project %2", title, m_project->name()));
0048 
0049     return task;
0050 }
0051 
0052 void ProjectPageModel::removeItem(const QModelIndex &index)
0053 {
0054     QVariant data = index.data(QueryTreeModelBase::ObjectRole);
0055     auto task = data.value<Domain::Task::Ptr>();
0056     Q_ASSERT(task);
0057     const auto job = m_taskRepository->remove(task);
0058     installHandler(job, i18n("Cannot remove task %1 from project %2", task->title(), m_project->name()));
0059 }
0060 
0061 void ProjectPageModel::promoteItem(const QModelIndex &index)
0062 {
0063     QVariant data = index.data(QueryTreeModelBase::ObjectRole);
0064     auto task = data.value<Domain::Task::Ptr>();
0065     Q_ASSERT(task);
0066     const auto job = m_taskRepository->promoteToProject(task);
0067     installHandler(job, i18n("Cannot promote task %1 to be a project", task->title()));
0068 }
0069 
0070 QAbstractItemModel *ProjectPageModel::createCentralListModel()
0071 {
0072     auto query = [this](const Domain::Task::Ptr &task) -> Domain::QueryResultInterface<Domain::Task::Ptr>::Ptr {
0073         if (!task)
0074             return m_projectQueries->findTopLevel(m_project);
0075         else
0076             return m_taskQueries->findChildren(task);
0077     };
0078 
0079     auto flags = [](const Domain::Task::Ptr &) {
0080         return Qt::ItemIsSelectable
0081              | Qt::ItemIsEnabled
0082              | Qt::ItemIsEditable
0083              | Qt::ItemIsDragEnabled
0084              | Qt::ItemIsUserCheckable
0085              | Qt::ItemIsDropEnabled;
0086     };
0087 
0088     auto data = [](const Domain::Task::Ptr &task, int role, int) -> QVariant {
0089         return defaultTaskData(task, role, TaskExtraDataPtr());
0090     };
0091 
0092     auto setData = [this](const Domain::Task::Ptr &task, const QVariant &value, int role) {
0093         if (role != Qt::EditRole && role != Qt::CheckStateRole) {
0094             return false;
0095         }
0096 
0097         const auto currentTitle = task->title();
0098         if (role == Qt::EditRole)
0099             task->setTitle(value.toString());
0100         else
0101             task->setDone(value.toInt() == Qt::Checked);
0102 
0103         const auto job = m_taskRepository->update(task);
0104         installHandler(job, i18n("Cannot modify task %1 in project %2", currentTitle, m_project->name()));
0105         return true;
0106     };
0107 
0108     auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const Domain::Task::Ptr &parentTask) {
0109         if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object")))
0110             return false;
0111 
0112         auto droppedTasks = mimeData->property("objects").value<Domain::Task::List>();
0113         if (droppedTasks.isEmpty())
0114             return false;
0115 
0116         using namespace std::placeholders;
0117         auto associate = std::function<KJob*(Domain::Task::Ptr)>();
0118         auto parentTitle = QString();
0119 
0120         if (parentTask) {
0121             associate = std::bind(&Domain::TaskRepository::associate, m_taskRepository, parentTask, _1);
0122             parentTitle = parentTask->title();
0123         } else {
0124             associate = std::bind(&Domain::ProjectRepository::associate, m_projectRepository, m_project, _1);
0125             parentTitle = m_project->name();
0126         }
0127 
0128         foreach(const Domain::Task::Ptr &childTask, droppedTasks) {
0129             const auto job = associate(childTask);
0130             installHandler(job, i18n("Cannot move task %1 as a sub-task of %2", childTask->title(), parentTitle));
0131         }
0132 
0133         return true;
0134     };
0135 
0136     auto drag = [](const Domain::Task::List &tasks) -> QMimeData* {
0137         if (tasks.isEmpty())
0138             return nullptr;
0139 
0140         auto data = new QMimeData;
0141         data->setData(QStringLiteral("application/x-zanshin-object"), "object");
0142         data->setProperty("objects", QVariant::fromValue(tasks));
0143         return data;
0144     };
0145 
0146     return new QueryTreeModel<Domain::Task::Ptr>(query, flags, data, setData, drop, drag, nullptr, this);
0147 }
0148 
0149 #include "moc_projectpagemodel.cpp"