diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,3 +15,6 @@ add_subdirectory(utils) add_subdirectory(widgets) +# templatexml +add_subdirectory(templatexml) + diff --git a/src/domain/CMakeLists.txt b/src/domain/CMakeLists.txt --- a/src/domain/CMakeLists.txt +++ b/src/domain/CMakeLists.txt @@ -12,6 +12,9 @@ project.cpp projectqueries.cpp projectrepository.cpp + projecttemplate.cpp + projecttemplatequeries.cpp + projecttemplaterepository.cpp queryresult.cpp queryresultinterface.cpp queryresultprovider.cpp diff --git a/src/domain/projecttemplate.h b/src/domain/projecttemplate.h new file mode 100644 --- /dev/null +++ b/src/domain/projecttemplate.h @@ -0,0 +1,62 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#ifndef DOMAIN_PROJECTTEMPLATE_H +#define DOMAIN_PROJECTTEMPLATE_H + +#include +#include +#include + +namespace Domain { + +class ProjectTemplate : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + +public: + typedef QSharedPointer Ptr; + typedef QList List; + + explicit ProjectTemplate(QObject *parent = Q_NULLPTR); + virtual ~ProjectTemplate(); + + QString name() const; + +public slots: + void setName(const QString &name); + +signals: + void nameChanged(const QString &name); + +private: + QString m_name; +}; + +} + +Q_DECLARE_METATYPE(Domain::ProjectTemplate::Ptr) + +#endif // DOMAIN_PROJECTTEMPLATE_H diff --git a/src/domain/projecttemplate.cpp b/src/domain/projecttemplate.cpp new file mode 100644 --- /dev/null +++ b/src/domain/projecttemplate.cpp @@ -0,0 +1,50 @@ +/* This file is part of Zanshin + + Copyright Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#include "projecttemplate.h" + +using namespace Domain; + +ProjectTemplate::ProjectTemplate(QObject *parent) + : QObject(parent) +{ +} + +ProjectTemplate::~ProjectTemplate() +{ +} + +QString ProjectTemplate::name() const +{ + return m_name; +} + +void ProjectTemplate::setName(const QString &name) +{ + if (m_name == name) + return; + + m_name = name; + emit nameChanged(name); +} diff --git a/src/domain/projecttemplatequeries.h b/src/domain/projecttemplatequeries.h new file mode 100644 --- /dev/null +++ b/src/domain/projecttemplatequeries.h @@ -0,0 +1,47 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + +#ifndef DOMAIN_PROJECTTEMPLATEQUERIES_H +#define DOMAIN_PROJECTTEMPLATEQUERIES_H + +#include "projecttemplate.h" +#include "queryresult.h" +#include "task.h" + +namespace Domain { + +class ProjectTemplateQueries +{ +public: + typedef QSharedPointer Ptr; + + ProjectTemplateQueries(); + virtual ~ProjectTemplateQueries(); + + virtual QStringList findAll() const = 0; + //virtual QueryResult::Ptr findTopLevel(ProjectTemplate::Ptr projectTemplate) const = 0; +}; + +} + +#endif // DOMAIN_PROJECTTEMPLATEQUERIES_H diff --git a/src/domain/projecttemplatequeries.cpp b/src/domain/projecttemplatequeries.cpp new file mode 100644 --- /dev/null +++ b/src/domain/projecttemplatequeries.cpp @@ -0,0 +1,36 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#include "projecttemplatequeries.h" + +using namespace Domain; + +ProjectTemplateQueries::ProjectTemplateQueries() +{ +} + +ProjectTemplateQueries::~ProjectTemplateQueries() +{ +} + diff --git a/src/domain/projecttemplaterepository.h b/src/domain/projecttemplaterepository.h new file mode 100644 --- /dev/null +++ b/src/domain/projecttemplaterepository.h @@ -0,0 +1,52 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + +#ifndef DOMAIN_PROJECTTEMPLATEREPOSITORY_H +#define DOMAIN_PROJECTTEMPLATEREPOSITORY_H + +#include "artifact.h" +#include "project.h" +#include "projecttemplate.h" + +class KJob; +namespace Domain { + +class ProjectTemplateRepository +{ +public: + typedef QSharedPointer Ptr; + + ProjectTemplateRepository(); + virtual ~ProjectTemplateRepository(); + + virtual KJob *create(ProjectTemplate::Ptr ProjectTemplate, Project::Ptr project) = 0; + + //virtual KJob *create(ProjectTemplate::Ptr projectTemplate, Project::Ptr project) = 0; + //virtual KJob *update(ProjectTemplate::Ptr projectTemplate) = 0; + //virtual KJob *remove(ProjectTemplate::Ptr projectTemplate) = 0; + +}; + +} + +#endif // DOMAIN_PROJECTTEMPLATEREPOSITORY_H diff --git a/src/domain/projecttemplaterepository.cpp b/src/domain/projecttemplaterepository.cpp new file mode 100644 --- /dev/null +++ b/src/domain/projecttemplaterepository.cpp @@ -0,0 +1,36 @@ +/* This file is part of Zanshin + + Copyright Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#include "projecttemplaterepository.h" + +using namespace Domain; + +ProjectTemplateRepository::ProjectTemplateRepository() +{ +} + +ProjectTemplateRepository::~ProjectTemplateRepository() +{ +} + diff --git a/src/presentation/CMakeLists.txt b/src/presentation/CMakeLists.txt --- a/src/presentation/CMakeLists.txt +++ b/src/presentation/CMakeLists.txt @@ -19,6 +19,7 @@ taskinboxpagemodel.cpp tasklistmodel.cpp workdaypagemodel.cpp + templatepagemodel.cpp ) add_library(presentation STATIC ${presentation_SRCS}) diff --git a/src/presentation/applicationmodel.h b/src/presentation/applicationmodel.h --- a/src/presentation/applicationmodel.h +++ b/src/presentation/applicationmodel.h @@ -46,6 +46,7 @@ Q_PROPERTY(QObject* availablePages READ availablePages) Q_PROPERTY(QObject* currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged) Q_PROPERTY(QObject* editor READ editor) + public: typedef QSharedPointer Ptr; diff --git a/src/presentation/availablenotepagesmodel.h b/src/presentation/availablenotepagesmodel.h --- a/src/presentation/availablenotepagesmodel.h +++ b/src/presentation/availablenotepagesmodel.h @@ -49,6 +49,8 @@ QObject *parent = Q_NULLPTR); QAbstractItemModel *pageListModel() Q_DECL_OVERRIDE; + QAbstractItemModel *projectListModel() Q_DECL_OVERRIDE; + QAbstractItemModel *templateListModel() Q_DECL_OVERRIDE; bool hasProjectPages() const Q_DECL_OVERRIDE; bool hasContextPages() const Q_DECL_OVERRIDE; @@ -57,6 +59,7 @@ QObject *createPageForIndex(const QModelIndex &index) Q_DECL_OVERRIDE; void addProject(const QString &name, const Domain::DataSource::Ptr &source) Q_DECL_OVERRIDE; + void addTemplate(const QString &name, const Domain::Project::Ptr &project) Q_DECL_OVERRIDE; void addContext(const QString &name) Q_DECL_OVERRIDE; void addTag(const QString &name) Q_DECL_OVERRIDE; void removeItem(const QModelIndex &index) Q_DECL_OVERRIDE; @@ -76,6 +79,9 @@ Domain::QueryResultProvider::Ptr m_rootsProvider; QObjectPtr m_inboxObject; QObjectPtr m_tagsObject; + + QAbstractItemModel *m_projectListModel; + QAbstractItemModel *m_templateListModel; }; } diff --git a/src/presentation/availablenotepagesmodel.cpp b/src/presentation/availablenotepagesmodel.cpp --- a/src/presentation/availablenotepagesmodel.cpp +++ b/src/presentation/availablenotepagesmodel.cpp @@ -64,6 +64,16 @@ return m_sortProxyModel; } +QAbstractItemModel *AvailableNotePagesModel::projectListModel() +{ + return m_projectListModel; +} + +QAbstractItemModel *AvailableNotePagesModel::templateListModel() +{ + return m_templateListModel; +} + bool AvailableNotePagesModel::hasProjectPages() const { return false; @@ -107,6 +117,11 @@ qFatal("Not supported"); } +void AvailableNotePagesModel::addTemplate(const QString &, const Domain::Project::Ptr &) +{ + qFatal("Not supported"); +} + void AvailableNotePagesModel::addContext(const QString &) { qFatal("Not supported"); diff --git a/src/presentation/availablepagesmodelinterface.h b/src/presentation/availablepagesmodelinterface.h --- a/src/presentation/availablepagesmodelinterface.h +++ b/src/presentation/availablepagesmodelinterface.h @@ -28,6 +28,7 @@ #include #include "domain/datasource.h" +#include "domain/project.h" #include "presentation/errorhandlingmodelbase.h" @@ -40,6 +41,8 @@ { Q_OBJECT Q_PROPERTY(QAbstractItemModel* pageListModel READ pageListModel) + Q_PROPERTY(QAbstractItemModel* projectListModel READ projectListModel) + Q_PROPERTY(QAbstractItemModel* templateListModel READ templateListModel) Q_PROPERTY(bool hasProjectPages READ hasProjectPages) Q_PROPERTY(bool hasContextPages READ hasContextPages) Q_PROPERTY(bool hasTagPages READ hasTagPages) @@ -47,6 +50,8 @@ explicit AvailablePagesModelInterface(QObject *parent = Q_NULLPTR); virtual QAbstractItemModel *pageListModel() = 0; + virtual QAbstractItemModel *projectListModel() = 0; + virtual QAbstractItemModel *templateListModel() = 0; virtual bool hasProjectPages() const = 0; virtual bool hasContextPages() const = 0; @@ -56,6 +61,7 @@ public slots: virtual void addProject(const QString &name, const Domain::DataSource::Ptr &source) = 0; + virtual void addTemplate(const QString &name, const Domain::Project::Ptr &project) = 0; virtual void addContext(const QString &name) = 0; virtual void addTag(const QString &name) = 0; virtual void removeItem(const QModelIndex &index) = 0; diff --git a/src/presentation/availabletaskpagesmodel.h b/src/presentation/availabletaskpagesmodel.h --- a/src/presentation/availabletaskpagesmodel.h +++ b/src/presentation/availabletaskpagesmodel.h @@ -33,6 +33,8 @@ #include "domain/projectrepository.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" +#include "domain/projecttemplatequeries.h" +#include "domain/projecttemplaterepository.h" #include "presentation/metatypes.h" @@ -51,9 +53,13 @@ const Domain::ContextRepository::Ptr &contextRepository, const Domain::TaskQueries::Ptr &taskQueries, const Domain::TaskRepository::Ptr &taskRepository, + const Domain::ProjectTemplateQueries::Ptr &projectTemplateQueries, + const Domain::ProjectTemplateRepository::Ptr &projectTemplateRepository, QObject *parent = Q_NULLPTR); QAbstractItemModel *pageListModel() Q_DECL_OVERRIDE; + QAbstractItemModel *projectListModel() Q_DECL_OVERRIDE; + QAbstractItemModel *templateListModel() Q_DECL_OVERRIDE; bool hasProjectPages() const Q_DECL_OVERRIDE; bool hasContextPages() const Q_DECL_OVERRIDE; @@ -62,14 +68,19 @@ QObject *createPageForIndex(const QModelIndex &index) Q_DECL_OVERRIDE; void addProject(const QString &name, const Domain::DataSource::Ptr &source) Q_DECL_OVERRIDE; + void addTemplate(const QString &name, const Domain::Project::Ptr &project) Q_DECL_OVERRIDE; void addContext(const QString &name) Q_DECL_OVERRIDE; void addTag(const QString &name) Q_DECL_OVERRIDE; void removeItem(const QModelIndex &index) Q_DECL_OVERRIDE; private: QAbstractItemModel *createPageListModel(); + QAbstractItemModel *createProjectListModel(); + QAbstractItemModel *createTemplateListModel(); QAbstractItemModel *m_pageListModel; + QAbstractItemModel *m_projectListModel; + QAbstractItemModel *m_templateListModel; Presentation::AvailablePagesSortFilterProxyModel *m_sortProxyModel; Domain::ProjectQueries::Ptr m_projectQueries; @@ -81,6 +92,9 @@ Domain::TaskQueries::Ptr m_taskQueries; Domain::TaskRepository::Ptr m_taskRepository; + Domain::ProjectTemplateQueries::Ptr m_projectTemplateQueries; + Domain::ProjectTemplateRepository::Ptr m_projectTemplateRepository; + Domain::QueryResultProvider::Ptr m_rootsProvider; QObjectPtr m_inboxObject; QObjectPtr m_workdayObject; diff --git a/src/presentation/availabletaskpagesmodel.cpp b/src/presentation/availabletaskpagesmodel.cpp --- a/src/presentation/availabletaskpagesmodel.cpp +++ b/src/presentation/availabletaskpagesmodel.cpp @@ -27,10 +27,16 @@ #include #include +#include +#include +#include + #include "domain/contextqueries.h" #include "domain/contextrepository.h" #include "domain/projectqueries.h" #include "domain/projectrepository.h" +#include "domain/projecttemplatequeries.h" +#include "domain/projecttemplaterepository.h" #include "domain/taskrepository.h" #include "presentation/availablepagessortfilterproxymodel.h" @@ -52,16 +58,22 @@ const Domain::ContextRepository::Ptr &contextRepository, const Domain::TaskQueries::Ptr &taskQueries, const Domain::TaskRepository::Ptr &taskRepository, + const Domain::ProjectTemplateQueries::Ptr &projectTemplateQueries, + const Domain::ProjectTemplateRepository::Ptr &projectTemplateRepository, QObject *parent) : AvailablePagesModelInterface(parent), m_pageListModel(Q_NULLPTR), + m_projectListModel(Q_NULLPTR), + m_templateListModel(Q_NULLPTR), m_sortProxyModel(Q_NULLPTR), m_projectQueries(projectQueries), m_projectRepository(projectRepository), m_contextQueries(contextQueries), m_contextRepository(contextRepository), m_taskQueries(taskQueries), - m_taskRepository(taskRepository) + m_taskRepository(taskRepository), + m_projectTemplateQueries(projectTemplateQueries), + m_projectTemplateRepository(projectTemplateRepository) { } @@ -78,6 +90,20 @@ return m_sortProxyModel; } +QAbstractItemModel *AvailableTaskPagesModel::projectListModel() +{ + if (!m_projectListModel) + m_projectListModel = createProjectListModel(); + return m_projectListModel; +} + +QAbstractItemModel *AvailableTaskPagesModel::templateListModel() +{ + if (!m_templateListModel) + m_templateListModel = createTemplateListModel(); + return m_templateListModel; +} + bool AvailableTaskPagesModel::hasProjectPages() const { return true; @@ -140,6 +166,14 @@ installHandler(job, tr("Cannot add project %1 in dataSource %2").arg(name).arg(source->name())); } +void AvailableTaskPagesModel::addTemplate(const QString &name, const Domain::Project::Ptr &project) +{ + auto projectTemplate = Domain::ProjectTemplate::Ptr::create(); + projectTemplate->setName(name); + const auto job = m_projectTemplateRepository->create(projectTemplate, project); + installHandler(job, tr("Cannot create template %1 from project %2").arg(name).arg(project->name())); +} + void AvailableTaskPagesModel::addContext(const QString &name) { auto context = Domain::Context::Ptr::create(); @@ -339,3 +373,76 @@ return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } + +QAbstractItemModel *AvailableTaskPagesModel::createProjectListModel() +{ + auto query = [this] (const Domain::Project::Ptr &project) -> Domain::QueryResultInterface::Ptr { + if (!project) + return m_projectQueries->findAll(); + else + return Domain::QueryResult::Ptr(); + }; + + auto flags = [](const Domain::Project::Ptr &) { + return Qt::ItemIsSelectable + | Qt::ItemIsEnabled + | Qt::ItemIsEditable + | Qt::ItemIsDragEnabled; + }; + + auto data = [](const Domain::Project::Ptr &project, int role) -> QVariant { + if (role != Qt::DisplayRole + && role != Qt::EditRole) { + return QVariant(); + } + + if (role == Qt::DisplayRole || role == Qt::EditRole) { + return project->name(); + } else { + return QVariant(); + } + }; + + auto setData = [this] (const Domain::Project::Ptr &project, const QVariant &value, int role) { + if (role != Qt::EditRole) { + return false; + } + + const auto currentName = project->name(); + project->setName(value.toString()); + const auto job = m_projectRepository->update(project); + installHandler(job, tr("Cannot modify project %1").arg(currentName)); + return true; + }; + + auto drop = [this] (const QMimeData *, Qt::DropAction, const Domain::Project::Ptr &) { + return false; + }; + + auto drag = [](const Domain::Project::List &) -> QMimeData* { + return Q_NULLPTR; + }; + + return new QueryTreeModel(query, flags, data, setData, drop, drag, this); +} + +QAbstractItemModel *AvailableTaskPagesModel::createTemplateListModel() +{ + QStringList stringList = m_projectTemplateQueries->findAll(); + /*QStringList stringList; + + QString path = QDir::currentPath(); + path.append("/Templates"); + + QDir directory(path); + //stringList = directory.entryList(QDir::Files | QDir::Hidden); + + QStringList filters; + filters << "*.xml"; //append your xml filter. You can add other filters here + + stringList = directory.entryList(filters, QDir::Files); + stringList.replaceInStrings(".xml", "");*/ + + QStringListModel *model = new QStringListModel(stringList); + return model; +} diff --git a/src/presentation/projectlistmodel.h b/src/presentation/projectlistmodel.h new file mode 100644 --- /dev/null +++ b/src/presentation/projectlistmodel.h @@ -0,0 +1,62 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#ifndef PRESENTATION_PROJECTLISTMODEL_H +#define PRESENTATION_PROJECTLISTMODEL_H + +#include + +#include "domain/queryresult.h" +#include "domain/projectrepository.h" + +namespace Presentation { + +class ProjectListModel : public QAbstractListModel +{ + Q_OBJECT +public: + typedef Domain::QueryResult ProjectList; + + explicit ProjectListModel(const ProjectList::Ptr &projectList, + const Domain::ProjectRepository::Ptr &repository, + QObject *parent = Q_NULLPTR); + ~ProjectListModel(); + + Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; + + int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE; + +private: + Domain::Project::Ptr projectForIndex(const QModelIndex &index) const; + bool isModelIndexValid(const QModelIndex &index) const; + + ProjectList::Ptr m_projectList; + Domain::ProjectRepository::Ptr m_repository; +}; + +} + +#endif // PRESENTATION_PROJECTLISTMODEL_H diff --git a/src/presentation/projectlistmodel.cpp b/src/presentation/projectlistmodel.cpp new file mode 100644 --- /dev/null +++ b/src/presentation/projectlistmodel.cpp @@ -0,0 +1,119 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#include "projectlistmodel.h" + +#include "domain/projectrepository.h" + +using namespace Presentation; + +ProjectListModel::ProjectListModel(const ProjectList::Ptr &projectList, const Domain::ProjectRepository::Ptr &repository, QObject *parent) + : QAbstractListModel(parent), + m_projectList(projectList), + m_repository(repository) +{ + m_projectList->addPreInsertHandler([this](const Domain::Project::Ptr &, int index) { + beginInsertRows(QModelIndex(), index, index); + }); + m_projectList->addPostInsertHandler([this](const Domain::Project::Ptr &, int) { + endInsertRows(); + }); + m_projectList->addPreRemoveHandler([this](const Domain::Project::Ptr &, int index) { + beginRemoveRows(QModelIndex(), index, index); + }); + m_projectList->addPostRemoveHandler([this](const Domain::Project::Ptr &, int) { + endRemoveRows(); + }); + m_projectList->addPostReplaceHandler([this](const Domain::Project::Ptr &, int idx) { + emit dataChanged(index(idx), index(idx)); + }); +} + +ProjectListModel::~ProjectListModel() +{ +} + +Qt::ItemFlags ProjectListModel::flags(const QModelIndex &index) const +{ + if (!isModelIndexValid(index)) { + return Qt::NoItemFlags; + } + + return QAbstractListModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsUserCheckable; +} + +int ProjectListModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + else + return m_projectList->data().size(); +} + +QVariant ProjectListModel::data(const QModelIndex &index, int role) const +{ + if (!isModelIndexValid(index)) { + return QVariant(); + } + + if (role != Qt::DisplayRole && role != Qt::CheckStateRole) { + return QVariant(); + } + + const auto project = projectForIndex(index); + //if (role == Qt::DisplayRole) + return project->name(); +} + +bool ProjectListModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!isModelIndexValid(index)) { + return false; + } + + if (role != Qt::EditRole && role != Qt::CheckStateRole) { + return false; + } + + auto project = projectForIndex(index); + //if (role == Qt::EditRole) { + project->setName(value.toString()); + //} + + m_repository->update(project); + return true; +} + +Domain::Project::Ptr ProjectListModel::projectForIndex(const QModelIndex &index) const +{ + return m_projectList->data().at(index.row()); +} + +bool ProjectListModel::isModelIndexValid(const QModelIndex &index) const +{ + return index.isValid() + && index.column() == 0 + && index.row() >= 0 + && index.row() < m_projectList->data().size(); +} diff --git a/src/presentation/templatepagemodel.h b/src/presentation/templatepagemodel.h new file mode 100644 --- /dev/null +++ b/src/presentation/templatepagemodel.h @@ -0,0 +1,68 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#ifndef PRESENTATION_TEMPLATEPAGEMODEL_H +#define PRESENTATION_TEMPLATEPAGEMODEL_H + +#include "presentation/pagemodel.h" + +#include "domain/project.h" +#include "domain/projectqueries.h" +#include "domain/projectrepository.h" +#include "domain/taskqueries.h" +#include "domain/taskrepository.h" + + +namespace Presentation { + +class TemplatePageModel : public PageModel +{ + Q_OBJECT +public: + explicit TemplatePageModel(const Domain::Project::Ptr &project, + const Domain::ProjectQueries::Ptr &projectQueries, + const Domain::ProjectRepository::Ptr &projectRepository, + const Domain::TaskQueries::Ptr &taskQueries, + const Domain::TaskRepository::Ptr &taskRepository, + QObject *parent = Q_NULLPTR); + + Domain::Project::Ptr project() const; + Domain::Artifact::Ptr addItem(const QString &title, const QModelIndex &parentIndex = QModelIndex()) Q_DECL_OVERRIDE; + void removeItem(const QModelIndex &index) Q_DECL_OVERRIDE; + void promoteItem(const QModelIndex &index) Q_DECL_OVERRIDE; + +private: + QAbstractItemModel *createCentralListModel() Q_DECL_OVERRIDE; + + Domain::Project::Ptr m_project; + Domain::ProjectQueries::Ptr m_projectQueries; + Domain::ProjectRepository::Ptr m_projectRepository; + + Domain::TaskQueries::Ptr m_taskQueries; + Domain::TaskRepository::Ptr m_taskRepository; +}; + +} + +#endif // PRESENTATION_TEMPLATEPAGEMODEL_H diff --git a/src/presentation/templatepagemodel.cpp b/src/presentation/templatepagemodel.cpp new file mode 100644 --- /dev/null +++ b/src/presentation/templatepagemodel.cpp @@ -0,0 +1,293 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + +#include "templatepagemodel.h" + +#include + +#include "domain/project.h" +#include "domain/projectqueries.h" +#include "domain/projectrepository.h" + +#include "presentation/querytreemodel.h" + +using namespace Presentation; + +TemplatePageModel::TemplatePageModel(const Domain::Project::Ptr &project, + const Domain::ProjectQueries::Ptr &projectQueries, + const Domain::ProjectRepository::Ptr &projectRepository, + const Domain::TaskQueries::Ptr &taskQueries, + const Domain::TaskRepository::Ptr &taskRepository, + QObject *parent) + : PageModel(parent), + m_project(project), + m_projectQueries(projectQueries), + m_projectRepository(projectRepository), + m_taskQueries(taskQueries), + m_taskRepository(taskRepository) + { + } + +Domain::Project::Ptr TemplatePageModel::project() const +{ + return m_project; +} + + +Domain::Artifact::Ptr TemplatePageModel::addItem(const QString &title, const QModelIndex &parentIndex) +{ + const auto parentData = parentIndex.data(QueryTreeModel::ObjectRole); + const auto parentArtifact = parentData.value(); + const auto parentTask = parentArtifact.objectCast(); + + auto task = Domain::Task::Ptr::create(); + task->setTitle(title); + + const auto job = parentTask ? m_taskRepository->createChild(task, parentTask) + : m_taskRepository->createInProject(task, m_project); + installHandler(job, tr("Cannot add task %1 in project %2").arg(title).arg(m_project->name())); + + return task; +} + +void TemplatePageModel::removeItem(const QModelIndex &index) +{ + QVariant data = index.data(QueryTreeModel::ObjectRole); + auto artifact = data.value(); + auto project = artifact.objectCast(); + Q_ASSERT(project); + const auto job = m_projectRepository->remove(project); + installHandler(job, tr("Cannot remove project %1").arg(project->name())); +} + +void TemplatePageModel::promoteItem(const QModelIndex &) +{ + qFatal("Not supported"); +} + +QAbstractItemModel *TemplatePageModel::createCentralListModel() +{ + auto query = [this] (const Domain::Project::Ptr &project) -> Domain::QueryResultInterface::Ptr { + if (!project) + return m_projectQueries->findAll(); + else + return Domain::QueryResult::Ptr(); + }; + + auto flags = [](const Domain::Project::Ptr &) { + return Qt::ItemIsSelectable + | Qt::ItemIsEnabled + | Qt::ItemIsEditable + | Qt::ItemIsDragEnabled; + }; + + auto data = [](const Domain::Project::Ptr &project, int role) -> QVariant { + if (role != Qt::DisplayRole + && role != Qt::EditRole) { + return QVariant(); + } + + if (role == Qt::DisplayRole || role == Qt::EditRole) { + return project->name(); + } else { + return QVariant(); + } + }; + + auto setData = [this] (const Domain::Project::Ptr &project, const QVariant &value, int role) { + if (role != Qt::EditRole) { + return false; + } + project->setName(value.toString()); + const auto job = m_projectRepository->update(project); + installHandler(job, tr("Cannot modify project %1 ").arg(project->name())); + return true; + }; + + auto drop = [this] (const QMimeData *, Qt::DropAction, const Domain::Project::Ptr &) { + return false; + }; + + auto drag = [](const Domain::Project::List &) -> QMimeData* { + return Q_NULLPTR; + }; + return new QueryTreeModel(query, flags, data, setData, drop, drag, this); +} + +/* +auto query = [this](const QObjectPtr &object) -> Domain::QueryResultInterface::Ptr { + if (!object) + return Domain::QueryResult::create(m_rootsProvider); + else if (object == m_projectsObject) + return Domain::QueryResult::copy(m_projectQueries->findAll()); + else if (object == m_contextsObject) + return Domain::QueryResult::copy(m_contextQueries->findAll()); + else + return Domain::QueryResult::Ptr(); +}; + +auto flags = [this](const QObjectPtr &object) { + const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable + | Qt::ItemIsEnabled + | Qt::ItemIsEditable + | Qt::ItemIsDropEnabled; + const Qt::ItemFlags immutableNodeFlags = Qt::ItemIsSelectable + | Qt::ItemIsEnabled + | Qt::ItemIsDropEnabled; + const Qt::ItemFlags structureNodeFlags = Qt::NoItemFlags; + + return object.objectCast() ? defaultFlags + : object.objectCast() ? defaultFlags + : object == m_inboxObject ? immutableNodeFlags + : object == m_workdayObject ? immutableNodeFlags + : structureNodeFlags; +}; + +auto data = [this](const QObjectPtr &object, int role) -> QVariant { + if (role != Qt::DisplayRole + && role != Qt::EditRole + && role != Qt::DecorationRole + && role != QueryTreeModelBase::IconNameRole) { + return QVariant(); + } + + if (role == Qt::EditRole + && (object == m_inboxObject + || object == m_workdayObject + || object == m_projectsObject + || object == m_contextsObject)) { + return QVariant(); + } + + if (role == Qt::DisplayRole || role == Qt::EditRole) { + return object->property("name").toString(); + } else if (role == Qt::DecorationRole || role == QueryTreeModelBase::IconNameRole) { + const QString iconName = object == m_inboxObject ? "mail-folder-inbox" + : (object == m_workdayObject) ? "go-jump-today" + : (object == m_projectsObject) ? "folder" + : (object == m_contextsObject) ? "folder" + : object.objectCast() ? "view-pim-notes" + : "view-pim-tasks"; + + if (role == Qt::DecorationRole) + return QVariant::fromValue(QIcon::fromTheme(iconName)); + else + return iconName; + } else { + return QVariant(); + } +}; + +auto setData = [this](const QObjectPtr &object, const QVariant &value, int role) { + if (role != Qt::EditRole) { + return false; + } + + if (object == m_inboxObject + || object == m_workdayObject + || object == m_projectsObject + || object == m_contextsObject) { + return false; + } + + if (auto project = object.objectCast()) { + const auto currentName = project->name(); + project->setName(value.toString()); + const auto job = m_projectRepository->update(project); + installHandler(job, tr("Cannot modify project %1").arg(currentName)); + } else if (auto context = object.objectCast()) { + const auto currentName = context->name(); + context->setName(value.toString()); + const auto job = m_contextRepository->update(context); + installHandler(job, tr("Cannot modify context %1").arg(currentName)); + } else { + Q_ASSERT(false); + } + + return true; +}; + +auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const QObjectPtr &object) { + if (!mimeData->hasFormat("application/x-zanshin-object")) + return false; + + auto droppedArtifacts = mimeData->property("objects").value(); + if (droppedArtifacts.isEmpty()) + return false; + + if (auto project = object.objectCast()) { + foreach (const auto &droppedArtifact, droppedArtifacts) { + const auto job = m_projectRepository->associate(project, droppedArtifact); + installHandler(job, tr("Cannot add %1 to project %2").arg(droppedArtifact->title()).arg(project->name())); + } + return true; + } else if (auto context = object.objectCast()) { + if (std::any_of(droppedArtifacts.begin(), droppedArtifacts.end(), + [](const Domain::Artifact::Ptr &droppedArtifact) { + return !droppedArtifact.objectCast(); + })) { + return false; + } + foreach (const auto &droppedArtifact, droppedArtifacts) { + auto task = droppedArtifact.staticCast(); + const auto job = m_contextRepository->associate(context, task); + installHandler(job, tr("Cannot add %1 to context %2").arg(task->title()).arg(context->name())); + } + return true; + } else if (object == m_inboxObject) { + foreach (const auto &droppedArtifact, droppedArtifacts) { + const auto job = m_projectRepository->dissociate(droppedArtifact); + installHandler(job, tr("Cannot move %1 to Inbox").arg(droppedArtifact->title())); + + if (auto task = droppedArtifact.objectCast()) { + Utils::JobHandler::install(job, [this, task] { + const auto dissociateJob = m_taskRepository->dissociateAll(task); + installHandler(dissociateJob, tr("Cannot move task %1 to Inbox").arg(task->title())); + }); + } + } + return true; + } else if (object == m_workdayObject) { + foreach (const auto &droppedArtifact, droppedArtifacts) { + + if (auto task = droppedArtifact.objectCast()) { + + task->setStartDate(Utils::DateTime::currentDateTime()); + const auto job = m_taskRepository->update(task); + + installHandler(job, tr("Cannot update task %1 to Workday").arg(task->title())); + } + } + return true; + } + + return false; +}; + +auto drag = [](const QObjectPtrList &) -> QMimeData* { + return Q_NULLPTR; +}; + +return new QueryTreeModel(query, flags, data, setData, drop, drag, this); +} +*/ diff --git a/src/templatexml/CMakeLists.txt b/src/templatexml/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/templatexml/CMakeLists.txt @@ -0,0 +1,15 @@ +set(templatexml_SRCS + availableprojecttemplate.cpp + projecttemplatequeries.cpp +) + +add_library(templatexml STATIC ${templatexml_SRCS}) +target_link_libraries(templatexml + KF5::AkonadiCalendar + KF5::AkonadiCore + KF5::AkonadiNotes + KF5::AkonadiWidgets + KF5::Mime + KF5::CalendarCore + KF5::IdentityManagement +) diff --git a/src/templatexml/availableprojecttemplate.h b/src/templatexml/availableprojecttemplate.h new file mode 100644 --- /dev/null +++ b/src/templatexml/availableprojecttemplate.h @@ -0,0 +1,87 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#ifndef TEMPLATEXML_AVAILABLEPROJECTTEMPLATE_H +#define TEMPLATEXML_AVAILABLEPROJECTTEMPLATE_H + +#include +#include +#include + +#include "domain/projecttemplaterepository.h" + +#include "akonadi/akonadiserializerinterface.h" +#include "akonadi/akonadistorageinterface.h" + +#include "domain/projectqueries.h" +#include "domain/taskqueries.h" +#include "domain/queryresult.h" +#include "domain/task.h" + + +class QModelIndex; + +class KJob; +namespace TemplateXML { + +class ProjectTemplateRepository : public QObject, public Domain::ProjectTemplateRepository +{ + Q_OBJECT +public: + typedef QSharedPointer Ptr; + + ProjectTemplateRepository(const Akonadi::StorageInterface::Ptr &storage, + const Akonadi::SerializerInterface::Ptr &serializer, + const Domain::ProjectQueries::Ptr &projectQueries, + const Domain::TaskQueries::Ptr &taskQueries); + + void writeXML(Domain::QueryResult::Ptr &inTasks); + //void writeXML2(Domain::QueryResult::Ptr &inTasks); + + KJob *create(Domain::ProjectTemplate::Ptr projectTemplate, Domain::Project::Ptr project) Q_DECL_OVERRIDE; + //KJob *create(Domain::ProjectTemplate::Ptr projectTemplate, Domain::Project::Ptr project) Q_DECL_OVERRIDE; + //KJob *update(Domain::ProjectTemplate::Ptr projectTemplate) Q_DECL_OVERRIDE; + //KJob *remove(Domain::ProjectTemplate::Ptr projectTemplate) Q_DECL_OVERRIDE; + +public slots: + void stopTimer(); + //void stopTimer2(); + +private: + Akonadi::StorageInterface::Ptr m_storage; + Akonadi::SerializerInterface::Ptr m_serializer; + Domain::ProjectQueries::Ptr m_projectQueries; + Domain::TaskQueries::Ptr m_taskQueries; + Domain::QueryResult::Ptr projectTasks; + Domain::QueryResult::Ptr currenTasks; + //QList tasks; + Domain::QueryResult::Ptr taskChildren; + //QList subTasks; + + +}; + +} + +#endif // TEMPLATEXML_AVAILABLEPROJECTTEMPLATE_H diff --git a/src/templatexml/availableprojecttemplate.cpp b/src/templatexml/availableprojecttemplate.cpp new file mode 100644 --- /dev/null +++ b/src/templatexml/availableprojecttemplate.cpp @@ -0,0 +1,136 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + +#include +#include +#include "availableprojecttemplate.h" + +#include "akonadi/akonadiitemfetchjobinterface.h" + +#include "utils/compositejob.h" + + + +using namespace TemplateXML; +QFile file; +QXmlStreamWriter xmlWriter; +QString taskname; +auto counter = 0; +auto size = 0; +auto level = 0; + +ProjectTemplateRepository::ProjectTemplateRepository(const Akonadi::StorageInterface::Ptr &storage, + const Akonadi::SerializerInterface::Ptr &serializer, + const Domain::ProjectQueries::Ptr &projectQueries, + const Domain::TaskQueries::Ptr &taskQueries) + : m_storage(storage), + m_serializer(serializer), + m_projectQueries(projectQueries), + m_taskQueries(taskQueries) +{ +} + +void ProjectTemplateRepository::writeXML(Domain::QueryResult::Ptr &inTasks) { + QTimer *timer = new QTimer(this); + timer->setSingleShot(true); + while(timer->isActive()); + currenTasks = inTasks; + connect(timer, SIGNAL(timeout()), this, SLOT(stopTimer())); + timer->start(2500); + +} + +void ProjectTemplateRepository::stopTimer() { + + QList tasks = currenTasks->data(); + + if (tasks.size()>0) { + auto size = 0; + level++; + foreach (const Domain::Task::Ptr &task, tasks) { + if(size == 0) { + xmlWriter.writeStartElement("Task"); + if(taskname.length()>0){ + xmlWriter.writeTextElement("ParentTask", taskname); + } + + } + size++; + //xmlWriter.writeStartElement("Task"+QString::number(size)); + xmlWriter.writeTextElement("SubTask", task->title()); + counter++; + //xmlWriter.writeTextElement("Title", task->title()); + Domain::QueryResult::Ptr children = m_taskQueries->findChildren(task); + if(size == tasks.size()) { + level--; + if(level == 0){ + xmlWriter.writeEndElement(); + } + counter--; + } + taskname = task->title(); + writeXML(children); + //connect(timer2, SIGNAL(timeout()), this, SLOT(stopTimer2())); + //timer2->start(2500); + //while(timer2->isActive()); + } + + } else { + //xmlWriter.writeEndElement(); + counter--; + } + + if (counter == 0) { + xmlWriter.writeEndElement(); + file.close(); + } +} + + +KJob *ProjectTemplateRepository::create(Domain::ProjectTemplate::Ptr projectTemplate, Domain::Project::Ptr project) +{ + QString templatename = projectTemplate->name(); + QString projectname = project->name(); + + projectTasks = m_projectQueries->findTopLevel(project); + QDir dir("Templates"); + if(!dir.exists()){ + QDir().mkdir("Templates"); + } + QString path = QDir::currentPath(); + path.append("/Templates/"); + path.append(projectTemplate->name()); + path.append(".xml"); + file.setFileName(path); + xmlWriter.setDevice(&file); + + file.open(QIODevice::WriteOnly); + + xmlWriter.setAutoFormatting(true); + xmlWriter.writeStartElement("Template"); + xmlWriter.writeTextElement("Name", templatename); + xmlWriter.writeTextElement("Project", projectname); + writeXML(projectTasks); + return Q_NULLPTR; + +} diff --git a/src/templatexml/projecttemplatequeries.h b/src/templatexml/projecttemplatequeries.h new file mode 100644 --- /dev/null +++ b/src/templatexml/projecttemplatequeries.h @@ -0,0 +1,57 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + +#ifndef PROJECTTEMPLATEQUERIES_H +#define PROJECTTEMPLATEQUERIES_H + +#include "domain/projecttemplatequeries.h" + +#include "akonadi/akonadilivequeryhelpers.h" +#include "akonadi/akonadilivequeryintegrator.h" + +namespace TemplateXML { + +class ProjectTemplateQueries : public Domain::ProjectTemplateQueries +{ +public: + typedef QSharedPointer Ptr; + + ProjectTemplateQueries(const Akonadi::StorageInterface::Ptr &storage, + const Akonadi::SerializerInterface::Ptr &serializer, + const Akonadi::MonitorInterface::Ptr &monitor); + + QStringList findAll() const Q_DECL_OVERRIDE; + //TaskResult::Ptr findTopLevel(Domain::ProjectTemplate::Ptr projectTemplate) const Q_DECL_OVERRIDE; + +private: + Akonadi::SerializerInterface::Ptr m_serializer; + Akonadi::LiveQueryHelpers::Ptr m_helpers; + Akonadi::LiveQueryIntegrator::Ptr m_integrator; + + //mutable ProjectTemplateQueryOutput::Ptr m_findAll; + //mutable QHash m_findTopLevel; +}; + +} + +#endif // PROJECTTEMPLATEQUERIES_H diff --git a/src/templatexml/projecttemplatequeries.cpp b/src/templatexml/projecttemplatequeries.cpp new file mode 100644 --- /dev/null +++ b/src/templatexml/projecttemplatequeries.cpp @@ -0,0 +1,62 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#include "projecttemplatequeries.h" + +#include +#include +#include +#include +#include +#include + +using namespace TemplateXML; + +ProjectTemplateQueries::ProjectTemplateQueries(const Akonadi::StorageInterface::Ptr &storage, const Akonadi::SerializerInterface::Ptr &serializer, const Akonadi::MonitorInterface::Ptr &monitor) + : m_serializer(serializer), + m_helpers(new Akonadi::LiveQueryHelpers(serializer, storage)), + m_integrator(new Akonadi::LiveQueryIntegrator(serializer, monitor)) +{ + +} + +QStringList ProjectTemplateQueries::findAll() const +{ + QStringList stringList; + + QString path = QDir::currentPath(); + path.append("/Templates"); + + QDir directory(path); + //stringList = directory.entryList(QDir::Files | QDir::Hidden); + + QStringList filters; + filters << "*.xml"; //append your xml filter. You can add other filters here + + stringList = directory.entryList(filters, QDir::Files); + stringList.replaceInStrings(".xml", ""); + + return stringList; + +} diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -10,6 +10,10 @@ messageboxinterface.cpp newprojectdialog.cpp newprojectdialoginterface.cpp + newtemplatedialog.cpp + newtemplatedialoginterface.cpp + newprojectfromtemplatedialog.cpp + newprojectfromtemplatedialoginterface.cpp pageview.cpp quickselectdialog.cpp quickselectdialoginterface.cpp @@ -19,6 +23,8 @@ qt5_wrap_ui(widgets_SRCS filterwidget.ui newprojectdialog.ui + newtemplatedialog.ui + newprojectfromtemplatedialog.ui ) add_library(widgets STATIC ${widgets_SRCS}) diff --git a/src/widgets/availablepagesview.h b/src/widgets/availablepagesview.h --- a/src/widgets/availablepagesview.h +++ b/src/widgets/availablepagesview.h @@ -35,6 +35,14 @@ #include "domain/datasource.h" #include "messageboxinterface.h" +#include "domain/queryresult.h" +#include "domain/project.h" +#include "domain/projectqueries.h" +#include "domain/projectrepository.h" +#include "domain/projecttemplate.h" +#include "domain/projecttemplatequeries.h" +#include "domain/projecttemplaterepository.h" + class QAbstractItemModel; class QModelIndex; class QTreeView; @@ -42,6 +50,8 @@ namespace Widgets { class NewProjectDialogInterface; +class NewTemplateDialogInterface; +class NewProjectFromTemplateDialogInterface; class QuickSelectDialogInterface; class AvailablePagesView : public QWidget @@ -50,6 +60,10 @@ public: typedef QSharedPointer NewProjectDialogPtr; typedef std::function ProjectDialogFactory; + typedef QSharedPointer NewTemplateDialogPtr; + typedef std::function TemplateDialogFactory; + typedef QSharedPointer NewProjectFromTemplateDialogPtr; + typedef std::function ProjectFromTemplateDialogFactory; typedef QSharedPointer QuickSelectDialogPtr; typedef std::function QuickSelectDialogFactory; @@ -62,6 +76,11 @@ Domain::DataSource::Ptr defaultProjectSource() const; ProjectDialogFactory projectDialogFactory() const; QuickSelectDialogFactory quickSelectDialogFactory() const; + QAbstractItemModel *projectListsModel() const; + Domain::Project::Ptr defaultProjectList() const; + QAbstractItemModel *templateListsModel() const; + Domain::Project::Ptr defaultTemplateList() const; + public slots: void setModel(QObject *model); @@ -71,6 +90,11 @@ void setQuickSelectDialogFactory(const QuickSelectDialogFactory &factory); void setMessageBoxInterface(const MessageBoxInterface::Ptr &interface); + void setProjectListsModel(QAbstractItemModel *lists); + void setDefaultProjectList(const Domain::Project::Ptr &list); + void setTemplateListsModel(QAbstractItemModel *lists); + void setDefaultTemplatetList(const Domain::ProjectTemplate::Ptr &list); + signals: void currentPageChanged(QObject *page); @@ -84,9 +108,12 @@ void onGoNextTriggered(); void onGoToTriggered(); void onInitTimeout(); - + void onAddTemplateTriggered(); + void onAddProjectFromTemplateTriggered(); private: QAction *m_addProjectAction; + QAction *m_addTemplateAction; + QAction *m_addProjectFromTemplateAction; QAction *m_addContextAction; QAction *m_addTagAction; QAction *m_removeAction; @@ -95,8 +122,21 @@ QObject *m_model; QAbstractItemModel *m_sources; Domain::DataSource::Ptr m_defaultSource; + + QAbstractItemModel *m_projects; + Domain::Project::Ptr m_defaultProject; + Domain::ProjectQueries::Ptr m_projectQueries; + Domain::ProjectRepository::Ptr m_projectRepository; + Domain::QueryResult::Ptr projectList; + Domain::QueryResult::Ptr templateList; + + QAbstractItemModel *m_templates; + Domain::ProjectTemplate::Ptr m_defaultTemplate; + QTreeView *m_pagesView; ProjectDialogFactory m_projectDialogFactory; + ProjectFromTemplateDialogFactory m_projectFromTemplateDialogFactory; + TemplateDialogFactory m_templateDialogFactory; QuickSelectDialogFactory m_quickSelectDialogFactory; MessageBoxInterface::Ptr m_messageBoxInterface; }; diff --git a/src/widgets/availablepagesview.cpp b/src/widgets/availablepagesview.cpp --- a/src/widgets/availablepagesview.cpp +++ b/src/widgets/availablepagesview.cpp @@ -31,15 +31,21 @@ #include #include #include +#include #include "presentation/metatypes.h" +#include "presentation/querytreemodel.h" #include "presentation/querytreemodelbase.h" +#include "presentation/projectpagemodel.h" #include "widgets/messagebox.h" #include "widgets/newprojectdialog.h" +#include "widgets/newtemplatedialog.h" +#include "widgets/newprojectfromtemplatedialog.h" #include "widgets/quickselectdialog.h" #include "domain/project.h" +#include "domain/projecttemplate.h" #include "domain/context.h" #include "domain/tag.h" @@ -49,12 +55,17 @@ AvailablePagesView::AvailablePagesView(QWidget *parent) : QWidget(parent), m_addProjectAction(new QAction(this)), + m_addTemplateAction(new QAction(this)), + m_addProjectFromTemplateAction(new QAction(this)), m_addContextAction(new QAction(this)), m_addTagAction(new QAction(this)), m_removeAction(new QAction(this)), m_model(Q_NULLPTR), m_sources(Q_NULLPTR), + m_projects(Q_NULLPTR), + m_templates(Q_NULLPTR), m_pagesView(new QTreeView(this)) + { m_pagesView->setObjectName("pagesView"); m_pagesView->header()->hide(); @@ -70,6 +81,18 @@ connect(m_addProjectAction, SIGNAL(triggered()), this, SLOT(onAddProjectTriggered())); actionBar->addAction(m_addProjectAction); + m_addTemplateAction->setObjectName("addTemplateAction"); + m_addTemplateAction->setText(tr("New template")); + m_addTemplateAction->setIcon(QIcon::fromTheme("action-albumfolder-importdir2")); + connect(m_addTemplateAction, SIGNAL(triggered()), this, SLOT(onAddTemplateTriggered())); + actionBar->addAction(m_addTemplateAction); + + m_addProjectFromTemplateAction->setObjectName("newProjectFromTemplateAction"); + m_addProjectFromTemplateAction->setText(tr("New project from template")); + m_addProjectFromTemplateAction->setIcon(QIcon::fromTheme("albumfolder-properties")); + connect(m_addProjectFromTemplateAction, SIGNAL(triggered()), this, SLOT(onAddProjectFromTemplateTriggered())); + actionBar->addAction(m_addProjectFromTemplateAction); + m_addContextAction->setObjectName("addContextAction"); m_addContextAction->setText(tr("New context")); m_addContextAction->setIcon(QIcon::fromTheme("view-pim-notes")); @@ -100,9 +123,19 @@ m_projectDialogFactory = [] (QWidget *parent) { return NewProjectDialogPtr(new NewProjectDialog(parent)); }; + + m_templateDialogFactory = [] (QWidget *parent) { + return NewTemplateDialogPtr(new NewTemplateDialog(parent)); + }; + + m_projectFromTemplateDialogFactory = [] (QWidget *parent) { + return NewProjectFromTemplateDialogPtr(new NewProjectFromTemplateDialog(parent)); + }; + m_quickSelectDialogFactory = [] (QWidget *parent) { return QuickSelectDialogPtr(new QuickSelectDialog(parent)); }; + m_messageBoxInterface = MessageBox::Ptr::create(); auto goPreviousAction = new QAction(this); @@ -126,6 +159,8 @@ connect(goToAction, SIGNAL(triggered(bool)), this, SLOT(onGoToTriggered())); m_actions.insert("pages_project_add", m_addProjectAction); + m_actions.insert("pages_template_add", m_addTemplateAction); + m_actions.insert("pages_project_from_template_add", m_addProjectFromTemplateAction); m_actions.insert("pages_context_add", m_addContextAction); m_actions.insert("pages_tag_add", m_addTagAction); m_actions.insert("pages_remove", m_removeAction); @@ -154,6 +189,16 @@ return m_defaultSource; } +QAbstractItemModel *AvailablePagesView::projectListsModel() const +{ + return m_projects; +} + +Domain::Project::Ptr AvailablePagesView::defaultProjectList() const +{ + return m_defaultProject; +} + AvailablePagesView::ProjectDialogFactory AvailablePagesView::projectDialogFactory() const { return m_projectDialogFactory; @@ -190,6 +235,15 @@ if (modelProperty.canConvert()) m_pagesView->setModel(modelProperty.value()); + QVariant projectListModelProperty = m_model->property("projectListModel"); + if (projectListModelProperty.canConvert()) + m_projects = projectListModelProperty.value(); + + QVariant templateListModelProperty = m_model->property("templateListModel"); + if (templateListModelProperty.canConvert()) + m_templates = templateListModelProperty.value(); + + connect(m_pagesView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(onCurrentChanged(QModelIndex))); @@ -221,6 +275,27 @@ m_messageBoxInterface = interface; } +void AvailablePagesView::setTemplateListsModel(QAbstractItemModel *templateList) +{ + m_templates = templateList; +} + +void AvailablePagesView::setDefaultTemplatetList(const Domain::ProjectTemplate::Ptr &projectTemplate) +{ + m_defaultTemplate = projectTemplate; +} + + +void AvailablePagesView::setProjectListsModel(QAbstractItemModel *projectList) +{ + m_projects = projectList; +} + +void AvailablePagesView::setDefaultProjectList(const Domain::Project::Ptr &project) +{ + m_defaultProject = project; +} + void AvailablePagesView::onCurrentChanged(const QModelIndex ¤t) { QObject *page = Q_NULLPTR; @@ -248,6 +323,24 @@ } } +void AvailablePagesView::onAddTemplateTriggered() { + NewTemplateDialogInterface::Ptr dialog = m_templateDialogFactory(this); + dialog->setProjectListsModel(m_projects); + if(dialog->exec() == QDialog::Accepted){ + m_defaultProject = dialog->projectList(); + QMetaObject::invokeMethod(m_model, "addTemplate", + Q_ARG(QString, dialog->name()), + Q_ARG(Domain::Project::Ptr, dialog->projectList())); + + } +} + +void AvailablePagesView::onAddProjectFromTemplateTriggered() { + NewProjectFromTemplateDialogInterface::Ptr dialog = m_projectFromTemplateDialogFactory(this); + dialog->setTemplateListsModel(m_templates); + dialog->exec(); +} + void AvailablePagesView::onAddContextTriggered() { const QString name = m_messageBoxInterface->askTextInput(this, tr("Add Context"), tr("Context name")); diff --git a/src/widgets/newprojectfromtemplatedialog.h b/src/widgets/newprojectfromtemplatedialog.h new file mode 100644 --- /dev/null +++ b/src/widgets/newprojectfromtemplatedialog.h @@ -0,0 +1,71 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + Copyright 2016 Thi Thanh Thuy Nguyen + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#ifndef WIDGETS_NEWPROJECTFROMTEMPLATEDIALOG_H +#define WIDGETS_NEWPROJECTFROMTEMPLATEDIALOG_H + +#include + +#include "widgets/newprojectfromtemplatedialoginterface.h" + +class QModelIndex; + +namespace Ui { + class NewProjectFromTemplateDialog; +} + +namespace Widgets { + +class NewProjectFromTemplateDialog : public QDialog, public NewProjectFromTemplateDialogInterface +{ + Q_OBJECT +public: + explicit NewProjectFromTemplateDialog(QWidget *parent = Q_NULLPTR); + ~NewProjectFromTemplateDialog(); + + int exec() Q_DECL_OVERRIDE; + + void accept() Q_DECL_OVERRIDE; + + QString name() const Q_DECL_OVERRIDE; + + void setTemplateListsModel(QAbstractItemModel *model1) Q_DECL_OVERRIDE; + Domain::ProjectTemplate::Ptr templateList() const Q_DECL_OVERRIDE; + +private slots: + void onNameTextChanged(const QString &text); + +private: + void applyDefaultProject(const QModelIndex &root); + + Ui::NewProjectFromTemplateDialog *ui; + QString m_name; + Domain::ProjectTemplate::Ptr m_template; + +}; + +} + +#endif // WIDGETS_NEWPROJECTFROMTEMPLATEDIALOG_H diff --git a/src/widgets/newprojectfromtemplatedialog.cpp b/src/widgets/newprojectfromtemplatedialog.cpp new file mode 100644 --- /dev/null +++ b/src/widgets/newprojectfromtemplatedialog.cpp @@ -0,0 +1,86 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + Copyright 2016 Thi Thanh Thuy Nguyen + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + +#include "newprojectfromtemplatedialog.h" +#include "ui_newprojectfromtemplatedialog.h" +#include +#include +#include +#include +#include "presentation/querytreemodelbase.h" + +using namespace Widgets; + +NewProjectFromTemplateDialog::NewProjectFromTemplateDialog(QWidget *parent) + : QDialog(parent), + ui(new Ui::NewProjectFromTemplateDialog) +{ + ui->setupUi(this); + + QObject::connect(ui->nameEdit, SIGNAL(textChanged(QString)), this, SLOT(onNameTextChanged(QString))); + onNameTextChanged(m_name); + +} + +NewProjectFromTemplateDialog::~NewProjectFromTemplateDialog() +{ + delete ui; +} + +int NewProjectFromTemplateDialog::exec() +{ + return QDialog::exec(); +} + +void NewProjectFromTemplateDialog::accept() +{ + m_name = ui->nameEdit->text(); + const auto selectedIndex = ui->templateListView->currentIndex(); + m_template = ui->templateListView->model()->data(selectedIndex, Presentation::QueryTreeModelBase::ObjectRole) + .value(); + QDialog::accept(); +} + +QString NewProjectFromTemplateDialog::name() const +{ + return m_name; +} + +Domain::ProjectTemplate::Ptr NewProjectFromTemplateDialog::templateList() const +{ + return m_template; +} + +void NewProjectFromTemplateDialog::onNameTextChanged(const QString &text) +{ + auto buttonOk = ui->buttonBox->button(QDialogButtonBox::Ok); + buttonOk->setEnabled(!text.isEmpty()); +} + +void NewProjectFromTemplateDialog::setTemplateListsModel(QAbstractItemModel *model) +{ + ui->templateListView->setModel(model); +} + + diff --git a/src/widgets/newprojectfromtemplatedialog.ui b/src/widgets/newprojectfromtemplatedialog.ui new file mode 100644 --- /dev/null +++ b/src/widgets/newprojectfromtemplatedialog.ui @@ -0,0 +1,104 @@ + + + NewProjectFromTemplateDialog + + + + 0 + 0 + 400 + 300 + + + + Add a project + + + + QLayout::SetFixedSize + + + + + + + false + + + Name + + + + + + + false + + + + 200 + 0 + + + + + + + + Template + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + NewProjectFromTemplateDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + NewProjectFromTemplateDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/widgets/newprojectfromtemplatedialoginterface.h b/src/widgets/newprojectfromtemplatedialoginterface.h new file mode 100644 --- /dev/null +++ b/src/widgets/newprojectfromtemplatedialoginterface.h @@ -0,0 +1,55 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + Copyright 2016 Thi Thanh Thuy Nguyen + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#ifndef WIDGETS_NEWPROJECTFROMTEMPLATEDIALOGINTERFACE_H +#define WIDGETS_NEWPROJECTFROMTEMPLATEDIALOGINTERFACE_H + +#include + +#include "domain/project.h" +#include "domain/projecttemplate.h" + +class QAbstractItemModel; + +namespace Widgets { + +class NewProjectFromTemplateDialogInterface +{ +public: + typedef QSharedPointer Ptr; + + virtual ~NewProjectFromTemplateDialogInterface(); + + virtual int exec() = 0; + + virtual QString name() const = 0; + + virtual void setTemplateListsModel(QAbstractItemModel *model) = 0; + virtual Domain::ProjectTemplate::Ptr templateList() const = 0; +}; + +} + +#endif // WIDGETS_NEWPROJECTFROMTEMPLATEDIALOGINTERFACE_H diff --git a/src/widgets/newprojectfromtemplatedialoginterface.cpp b/src/widgets/newprojectfromtemplatedialoginterface.cpp new file mode 100644 --- /dev/null +++ b/src/widgets/newprojectfromtemplatedialoginterface.cpp @@ -0,0 +1,32 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + Copyright 2016 Thi Thanh Thuy Nguyen + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#include "newprojectfromtemplatedialoginterface.h" + +using namespace Widgets; + +NewProjectFromTemplateDialogInterface::~NewProjectFromTemplateDialogInterface() +{ +} diff --git a/src/widgets/newtemplatedialog.h b/src/widgets/newtemplatedialog.h new file mode 100644 --- /dev/null +++ b/src/widgets/newtemplatedialog.h @@ -0,0 +1,71 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + Copyright 2016 Thi Thanh Thuy Nguyen + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#ifndef WIDGETS_NEWTEMPLATEDIALOG_H +#define WIDGETS_NEWTEMPLATEDIALOG_H + +#include + +#include "widgets/newtemplatedialoginterface.h" + +class QModelIndex; + +namespace Ui { + class NewTemplateDialog; +} + +namespace Widgets { + +class NewTemplateDialog : public QDialog, public NewTemplateDialogInterface +{ + Q_OBJECT +public: + explicit NewTemplateDialog(QWidget *parent = Q_NULLPTR); + ~NewTemplateDialog(); + + int exec() Q_DECL_OVERRIDE; + + void accept() Q_DECL_OVERRIDE; + + QString name() const Q_DECL_OVERRIDE; + + void setProjectListsModel(QAbstractItemModel *model1) Q_DECL_OVERRIDE; + Domain::Project::Ptr projectList() const Q_DECL_OVERRIDE; + +private slots: + void onNameTextChanged(const QString &text); + +private: + void applyDefaultProject(const QModelIndex &root); + + Ui::NewTemplateDialog *ui; + QString m_name; + Domain::Project::Ptr m_project; + +}; + +} + +#endif // WIDGETS_NEWTEMPLATEDIALOG_H diff --git a/src/widgets/newtemplatedialog.cpp b/src/widgets/newtemplatedialog.cpp new file mode 100644 --- /dev/null +++ b/src/widgets/newtemplatedialog.cpp @@ -0,0 +1,86 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + Copyright 2016 Thi Thanh Thuy Nguyen + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + +#include "newtemplatedialog.h" +#include "ui_newtemplatedialog.h" +#include +#include +#include +#include +#include "presentation/querytreemodelbase.h" + +using namespace Widgets; + +NewTemplateDialog::NewTemplateDialog(QWidget *parent) + : QDialog(parent), + ui(new Ui::NewTemplateDialog) +{ + ui->setupUi(this); + + QObject::connect(ui->nameEdit, SIGNAL(textChanged(QString)), this, SLOT(onNameTextChanged(QString))); + onNameTextChanged(m_name); + +} + +NewTemplateDialog::~NewTemplateDialog() +{ + delete ui; +} + +int NewTemplateDialog::exec() +{ + return QDialog::exec(); +} + +void NewTemplateDialog::accept() +{ + m_name = ui->nameEdit->text(); + const auto selectedIndex = ui->projectListView->currentIndex(); + m_project = ui->projectListView->model()->data(selectedIndex, Presentation::QueryTreeModelBase::ObjectRole) + .value(); + QDialog::accept(); +} + +QString NewTemplateDialog::name() const +{ + return m_name; +} + +Domain::Project::Ptr NewTemplateDialog::projectList() const +{ + return m_project; +} + +void NewTemplateDialog::onNameTextChanged(const QString &text) +{ + auto buttonOk = ui->buttonBox->button(QDialogButtonBox::Ok); + buttonOk->setEnabled(!text.isEmpty()); +} + +void NewTemplateDialog::setProjectListsModel(QAbstractItemModel *model) +{ + ui->projectListView->setModel(model); +} + + diff --git a/src/widgets/newtemplatedialog.ui b/src/widgets/newtemplatedialog.ui new file mode 100644 --- /dev/null +++ b/src/widgets/newtemplatedialog.ui @@ -0,0 +1,98 @@ + + + NewTemplateDialog + + + + 0 + 0 + 400 + 300 + + + + Add a project + + + + QLayout::SetFixedSize + + + + + + + Name + + + + + + + + 200 + 0 + + + + + + + + Project + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + NewTemplateDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + NewTemplateDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/widgets/newtemplatedialoginterface.h b/src/widgets/newtemplatedialoginterface.h new file mode 100644 --- /dev/null +++ b/src/widgets/newtemplatedialoginterface.h @@ -0,0 +1,54 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + Copyright 2016 Thi Thanh Thuy Nguyen + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#ifndef WIDGETS_NEWTEMPLATEDIALOGINTERFACE_H +#define WIDGETS_NEWTEMPLATEDIALOGINTERFACE_H + +#include + +#include "domain/project.h" + +class QAbstractItemModel; + +namespace Widgets { + +class NewTemplateDialogInterface +{ +public: + typedef QSharedPointer Ptr; + + virtual ~NewTemplateDialogInterface(); + + virtual int exec() = 0; + + virtual QString name() const = 0; + + virtual void setProjectListsModel(QAbstractItemModel *model) = 0; + virtual Domain::Project::Ptr projectList() const = 0; +}; + +} + +#endif // WIDGETS_NEWTEMPLATEDIALOGINTERFACE_H diff --git a/src/widgets/newtemplatedialoginterface.cpp b/src/widgets/newtemplatedialoginterface.cpp new file mode 100644 --- /dev/null +++ b/src/widgets/newtemplatedialoginterface.cpp @@ -0,0 +1,32 @@ +/* This file is part of Zanshin + + Copyright 2016 Rottana Ly + Copyright 2016 Thi Thanh Thuy Nguyen + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. +*/ + + +#include "newtemplatedialoginterface.h" + +using namespace Widgets; + +NewTemplateDialogInterface::~NewTemplateDialogInterface() +{ +} diff --git a/src/zanshin/app/CMakeLists.txt b/src/zanshin/app/CMakeLists.txt --- a/src/zanshin/app/CMakeLists.txt +++ b/src/zanshin/app/CMakeLists.txt @@ -11,6 +11,7 @@ domain presentation scripting + templatexml utils widgets ) diff --git a/src/zanshin/app/dependencies.cpp b/src/zanshin/app/dependencies.cpp --- a/src/zanshin/app/dependencies.cpp +++ b/src/zanshin/app/dependencies.cpp @@ -41,6 +41,9 @@ #include "presentation/availablesourcesmodel.h" #include "presentation/availabletaskpagesmodel.h" +#include "templatexml/availableprojecttemplate.h" +#include "templatexml/projecttemplatequeries.h" + #include "utils/dependencymanager.h" void App::initializeDependencies() @@ -87,11 +90,22 @@ Akonadi::SerializerInterface*, Akonadi::MonitorInterface*)>(); + deps.add(); + deps.add(); + deps.add(); + deps.add([] (Utils::DependencyManager *deps) { auto model = new Presentation::ArtifactEditorModel; auto repository = deps->create(); @@ -112,9 +126,12 @@ Domain::ContextQueries*, Domain::ContextRepository*, Domain::TaskQueries*, - Domain::TaskRepository*)>(); + Domain::TaskRepository*, + Domain::ProjectTemplateQueries*, + Domain::ProjectTemplateRepository*)>(); deps.add(); + } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,6 +15,7 @@ domain presentation scripting + templatexml utils widgets ) @@ -34,6 +35,7 @@ domain presentation scripting + templatexml utils widgets KF5::AkonadiXml diff --git a/tests/features/zanshin/features/step_definitions/CMakeLists.txt b/tests/features/zanshin/features/step_definitions/CMakeLists.txt --- a/tests/features/zanshin/features/step_definitions/CMakeLists.txt +++ b/tests/features/zanshin/features/step_definitions/CMakeLists.txt @@ -23,5 +23,6 @@ domain presentation scripting + templatexml utils ) diff --git a/tests/units/presentation/applicationmodeltest.cpp b/tests/units/presentation/applicationmodeltest.cpp --- a/tests/units/presentation/applicationmodeltest.cpp +++ b/tests/units/presentation/applicationmodeltest.cpp @@ -58,6 +58,8 @@ : Presentation::AvailablePagesModelInterface(parent) {} QAbstractItemModel *pageListModel() Q_DECL_OVERRIDE { return Q_NULLPTR; } + QAbstractItemModel *projectListModel() Q_DECL_OVERRIDE { return Q_NULLPTR; } + QAbstractItemModel *templateListModel() Q_DECL_OVERRIDE { return Q_NULLPTR; } bool hasProjectPages() const Q_DECL_OVERRIDE { return false; } bool hasContextPages() const Q_DECL_OVERRIDE { return false; } @@ -66,6 +68,7 @@ QObject *createPageForIndex(const QModelIndex &) Q_DECL_OVERRIDE { return Q_NULLPTR; } void addProject(const QString &, const Domain::DataSource::Ptr &) Q_DECL_OVERRIDE {} + void addTemplate(const QString &, const Domain::Project::Ptr &) Q_DECL_OVERRIDE {} void addContext(const QString &) Q_DECL_OVERRIDE {} void addTag(const QString &) Q_DECL_OVERRIDE {} void removeItem(const QModelIndex &) Q_DECL_OVERRIDE {} diff --git a/tests/units/presentation/availabletaskpagesmodeltest.cpp b/tests/units/presentation/availabletaskpagesmodeltest.cpp --- a/tests/units/presentation/availabletaskpagesmodeltest.cpp +++ b/tests/units/presentation/availabletaskpagesmodeltest.cpp @@ -59,7 +59,7 @@ void shouldDeclareOnlyProjectAndContextPages() { // GIVEN - Presentation::AvailableTaskPagesModel pages({}, {}, {}, {}, {}, {}); + Presentation::AvailableTaskPagesModel pages({}, {}, {}, {}, {}, {}, {},{}); // THEN QVERIFY(pages.hasProjectPages()); @@ -111,7 +111,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - taskRepositoryMock.getInstance()); + taskRepositoryMock.getInstance(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); @@ -345,7 +347,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); @@ -385,7 +389,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); @@ -430,7 +436,9 @@ contextQueriesMock.getInstance(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); @@ -481,13 +489,14 @@ Utils::MockObject projectRepositoryMock; - Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); @@ -524,7 +533,9 @@ Domain::ContextQueries::Ptr(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); // WHEN pages.addProject("Foo", source); @@ -554,7 +565,9 @@ Domain::ContextQueries::Ptr(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); @@ -579,7 +592,9 @@ Domain::ContextQueries::Ptr(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); // WHEN pages.addContext("Foo"); @@ -604,7 +619,9 @@ Domain::ContextQueries::Ptr(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); @@ -647,7 +664,9 @@ contextQueriesMock.getInstance(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); QAbstractItemModel *model = pages.pageListModel(); @@ -694,7 +713,9 @@ contextQueriesMock.getInstance(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); @@ -745,7 +766,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); QAbstractItemModel *model = pages.pageListModel(); @@ -791,7 +814,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - Domain::TaskRepository::Ptr()); + Domain::TaskRepository::Ptr(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); @@ -856,7 +881,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - taskRepositoryMock.getInstance()); + taskRepositoryMock.getInstance(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); @@ -920,7 +947,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - taskRepositoryMock.getInstance()); + taskRepositoryMock.getInstance(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); @@ -985,7 +1014,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - taskRepositoryMock.getInstance()); + taskRepositoryMock.getInstance(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); @@ -1051,7 +1082,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - taskRepositoryMock.getInstance()); + taskRepositoryMock.getInstance(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); @@ -1105,7 +1138,9 @@ contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), - taskRepositoryMock.getInstance()); + taskRepositoryMock.getInstance(), + Domain::ProjectTemplateQueries::Ptr(), + Domain::ProjectTemplateRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); diff --git a/tests/units/widgets/availablepagesviewtest.cpp b/tests/units/widgets/availablepagesviewtest.cpp --- a/tests/units/widgets/availablepagesviewtest.cpp +++ b/tests/units/widgets/availablepagesviewtest.cpp @@ -134,6 +134,12 @@ sources << source; } + void addTemplate(const QString &name, const Domain::Project::Ptr &project) + { + projectTemplateNames << name; + projects << project; + } + void addContext(const QString &name) { contextNames << name; @@ -154,9 +160,11 @@ public: QStringList projectNames; + QStringList projectTemplateNames; QStringList contextNames; QStringList tagNames; QList sources; + QList projects; QString projectRemoved; };