diff --git a/src/welcome/WelcomeView.cpp b/src/welcome/WelcomeView.cpp index 8236e171..c77b3b3e 100644 --- a/src/welcome/WelcomeView.cpp +++ b/src/welcome/WelcomeView.cpp @@ -1,404 +1,420 @@ /* This file is part of the KDE project Copyright (C) 2017 Dag Andersen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // clazy:excludeall=qstring-arg #include "WelcomeView.h" #include #include "kptcommand.h" #include "kptdebug.h" #include "Help.h" #include "kptpart.h" #include "kptmaindocument.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include const QLoggingCategory &PLANWELCOME_LOG() { static const QLoggingCategory category("calligra.plan.welcome"); return category; } #define debugWelcome qCDebug(PLANWELCOME_LOG)< actions); }; } using namespace KPlato; RecentFilesModel::RecentFilesModel(QObject *parent) : QStandardItemModel(parent) { } Qt::ItemFlags RecentFilesModel::flags(const QModelIndex &idx) const { Qt::ItemFlags f = (QStandardItemModel::flags(idx) & ~Qt::ItemIsEditable); return f; } QVariant RecentFilesModel::data(const QModelIndex &idx, int role) const { switch(role) { case Qt::DecorationRole: return QIcon::fromTheme(QStringLiteral("document-open")); case Qt::FontRole: { break; } default: break; } return QStandardItemModel::data(idx, role); } void RecentFilesModel::populate(const QList actions) { clear(); setColumnCount(1); setRowCount(actions.count()); QModelIndex idx = index(rowCount()-1, 0); for (const QAction *a : actions) { // KRecentFilesAction format: [] // so we split it up and remove the [] QString s = a->text(); QString name = s.left(s.indexOf('[')); QString file = s.mid(s.indexOf('[')+1); file = file.left(file.lastIndexOf(']')); QString t = QString("%1\n%2").arg(name, file); setData(idx, t, Qt::EditRole); setData(idx, file, Qt::UserRole+1); idx = idx.sibling(idx.row()-1, idx.column()); } } //----------------------------------- WelcomeView::WelcomeView(KoPart *part, KoDocument *doc, QWidget *parent) : ViewBase(part, doc, parent) , m_projectdialog(0) , m_filedialog(0) { ui.setupUi(this); ui.recentProjects->setBackgroundRole(QPalette::Midlight); ui.projectTemplates->setBackgroundRole(QPalette::Midlight); Help::add(ui.newProjectBtn, xi18nc("@info:whatsthis", "Create a new project" "" "Creates a new project with default values defined in" " Settings." "Opens the project dialog" " so you can define project specific properties like" " Project Name," " Target Start" " and - End times." "More..." "", Help::page("Creating_a_Project"))); Help::add(ui.createResourceFileBtn, xi18nc("@info:whatsthis", "Shared resources" "" "Create a shared resources file." "This enables you to only create your resources once," " you just refer to your resources file when you create a new project." "These resources can then be shared between projects" " to avoid overbooking resources across projects." "Shared resources must be defined in a separate file." "More..." "", Help::page("Managing_Resources"))); Help::add(ui.recentProjects, xi18nc("@info:whatsthis", "Recent Projects" "" "A list of the 10 most recent project files opened." "" "This enables you to quickly open projects you have worked on recently." "")); Help::add(ui.introductionBtn, xi18nc("@info:whatsthis", "Introduction to <application>Plan</application>" "" "These introductory pages gives you hints and tips on what" " you can use Plan for, and how to use it." "")); Help::add(ui.contextHelp, xi18nc("@info:whatsthis", "Context help" "" "Help is available many places using What's This." "It is activated using the menu entry Help->What's this?" " or the keyboard shortcut Shift+F1." "" "In dialogs it is available via the ? in the dialog title bar." "" "If you see More... in the text," " pressing it will display more information from online resources in your browser." "", Help::page("Context_Help"))); m_model = new RecentFilesModel(this); ui.recentProjects->setModel(m_model); ui.recentProjects->setSelectionMode(QAbstractItemView::SingleSelection); setProjectTemplatesModel(); setupGui(); connect(ui.newProjectBtn, &QAbstractButton::clicked, this, &WelcomeView::slotNewProject); connect(ui.createResourceFileBtn, &QAbstractButton::clicked, this, &WelcomeView::slotCreateResourceFile); connect(ui.openProjectBtn, &QAbstractButton::clicked, this, &WelcomeView::slotOpenProject); connect(ui.introductionBtn, &QAbstractButton::clicked, this, &WelcomeView::showIntroduction); connect(ui.recentProjects, &QAbstractItemView::activated, this, &WelcomeView::slotRecentFileSelected); connect(ui.projectTemplates, &QAbstractItemView::activated, this, &WelcomeView::slotOpenProjectTemplate); connect(mainWindow(), &KoMainWindow::loadCompleted, this, &WelcomeView::finished); } WelcomeView::~WelcomeView() { debugWelcome; } Project *WelcomeView::project() const { return koDocument() ? koDocument()->project() : nullptr; } void WelcomeView::setRecentFiles(const QList &actions) { m_model->populate(actions); } void WelcomeView::updateReadWrite(bool /*readwrite */) { } void WelcomeView::setGuiActive(bool activate) { debugPlan<isEmpty() ? koDocument()->documentPart() : nullptr; if (url.isValid()) { emit recentProject(url, part); } } } void WelcomeView::slotContextMenuRequested(const QModelIndex &/*index*/, const QPoint& /*pos */) { //debugPlan<config().setDefaultValues(*p); if (!m_projectdialog) { m_projectdialog = new MainProjectDialog(*p, this, false /*edit*/); connect(m_projectdialog.data(), &MainProjectDialog::dialogFinished, this, &WelcomeView::slotProjectEditFinished); connect(m_projectdialog.data(), &MainProjectDialog::sigLoadSharedResources, this, &WelcomeView::slotLoadSharedResources); } m_projectdialog->open(); } } void WelcomeView::slotProjectEditFinished(int result) { MainProjectDialog *dia = qobject_cast(sender()); if (dia == 0) { return; } if (result == QDialog::Accepted) { MacroCommand *cmd = dia->buildCommand(); if (cmd) { cmd->execute(); delete cmd; koDocument()->setModified(true); } emit projectCreated(); emit selectDefaultView(); emit finished(); } dia->deleteLater(); } void WelcomeView::slotCreateResourceFile() { QString file = QStandardPaths::locate(QStandardPaths::AppDataLocation, "templates/.source/SharedResources.plant"); emit openTemplate(QUrl::fromUserInput(file)); emit finished(); } void WelcomeView::slotOpenProject() { Project *p = project(); if (p) { KoFileDialog filedialog(this, KoFileDialog::OpenFile, "OpenDocument"); filedialog.setCaption(i18n("Open Document")); filedialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); filedialog.setMimeTypeFilters(koApp->mimeFilter(KoFilterManager::Import)); filedialog.setHideNameFilterDetailsOption(); KoPart *part = koDocument()->isEmpty() ? koDocument()->documentPart() : nullptr; QUrl url = QUrl::fromUserInput(filedialog.filename()); if (!url.isEmpty()) { mainWindow()->openDocument(part, url); } } } void WelcomeView::slotOpenProjectTemplate(const QModelIndex &idx) { if (idx.isValid()) { QString file = idx.data(Qt::UserRole+1).toString(); QUrl url = QUrl::fromUserInput(file); debugWelcome<documentPart(); bool ok = false; if (part && url.isValid()) { ok = part->openProjectTemplate(url); } if (ok) { Project *p = part->document()->project(); Q_ASSERT(p); MainProjectDialog dlg(*p, nullptr, false /*edit*/); if (dlg.exec()) { MacroCommand *cmd = dlg.buildCommand(); if (cmd) { cmd->execute(); delete cmd; part->document()->setModified(true); if (part->document()->url().isEmpty() && !p->name().isEmpty()) { part->document()->setUrl(QUrl(p->name() + ".plan")); } emit finished(); } } else { warnWelcome<<"cancelled dialog"; koDocument()->initEmpty(); } } else { warnWelcome<<"Failed to load template:"<(sender()); if (dia == 0) { return; } if (result == QDialog::Accepted) { QUrl url = QUrl::fromUserInput(dia->filename()); KoPart *part = koDocument()->isEmpty() ? nullptr : koDocument()->documentPart(); if (!url.isEmpty() && mainWindow()->openDocument(part, url)) { emit finished(); } } dia->deleteLater(); } void WelcomeView::slotLoadSharedResources(const QString &file, const QUrl &projects, bool loadProjectsAtStartup) { QUrl url(file); if (url.scheme().isEmpty()) { url.setScheme("file"); } if (url.isValid()) { emit loadSharedResources(url, loadProjectsAtStartup ? projects :QUrl()); } } void WelcomeView::setProjectTemplatesModel() { QStandardItemModel *m = new QStandardItemModel(ui.projectTemplates); const ConfigBase &config = koDocument()->project()->config(); const QStringList dirs = config.projectTemplatePaths(); + bool addgroups = dirs.count() > 1; + ui.projectTemplates->setRootIsDecorated(addgroups); for (const QString &path : dirs) { + QStandardItem *parent = nullptr; + if (addgroups) { + QString p = path; + if (p.endsWith('/')) { + p.remove(p.length()-1, 1); + } + p = p.mid(p.lastIndexOf('/')+1); + parent = new QStandardItem(p); + m->appendRow(parent); + } QDir dir(path, "*.plant"); for (const QString &file : dir.entryList(QDir::Files)) { QStandardItem *item = new QStandardItem(file.left(file.lastIndexOf(".plant"))); item->setData(QString(path + '/' + file)); item->setToolTip(item->data().toString()); item->setIcon(koIcon("document-new-from-template")); - m->appendRow(item); + if (parent) { + parent->appendRow(item); + } else { + m->appendRow(item); + } } } delete ui.projectTemplates->model(); ui.projectTemplates->setModel(m); }