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