From kde-commits Tue Sep 09 19:52:22 2014 From: Michal Humpula Date: Tue, 09 Sep 2014 19:52:22 +0000 To: kde-commits Subject: [kate] addons/project: project: auto detect git/svn/hg repositories Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=141029235617502 Git commit 8ec7aea613ed45243b4c80ff11ccde64f73c2c36 by Michal Humpula. Committed on 08/09/2014 at 16:18. Pushed by michalhumpula into branch 'master'. project: auto detect git/svn/hg repositories Enable possibility to fallback to autogenarated in memory stub projects for different repositories (git, mercurial, subversion), when .kateproject file is not found, but repository folder is. GUI: project plugin has now plugin config page REVIEW: 120103 M +1 -0 addons/project/CMakeLists.txt M +14 -4 addons/project/kateproject.cpp M +9 -4 addons/project/kateproject.h A +109 -0 addons/project/kateprojectconfigpage.cpp [License: LGPL = (v2+)] A +55 -0 addons/project/kateprojectconfigpage.h [License: LGPL (v= 2+)] M +143 -2 addons/project/kateprojectplugin.cpp M +21 -0 addons/project/kateprojectplugin.h http://commits.kde.org/kate/8ec7aea613ed45243b4c80ff11ccde64f73c2c36 diff --git a/addons/project/CMakeLists.txt b/addons/project/CMakeLists.txt index 5a38c57..e9ee95a 100644 --- a/addons/project/CMakeLists.txt +++ b/addons/project/CMakeLists.txt @@ -19,6 +19,7 @@ set(kateprojectplugin_PART_SRCS kateprojectinfoviewterminal.cpp kateprojectinfoviewcodeanalysis.cpp kateprojectinfoviewnotes.cpp + kateprojectconfigpage.cpp ) = add_library (kateprojectplugin MODULE ${kateprojectplugin_PART_SRCS}) diff --git a/addons/project/kateproject.cpp b/addons/project/kateproject.cpp index 20417e5..343d9d6 100644 --- a/addons/project/kateproject.cpp +++ b/addons/project/kateproject.cpp @@ -72,7 +72,7 @@ KateProject::~KateProject() saveNotesDocument(); } = -bool KateProject::load(const QString &fileName) +bool KateProject::loadFromFile(const QString &fileName) { /** * bail out if already fileName set! @@ -109,15 +109,25 @@ bool KateProject::reload(bool force) const QByteArray jsonData =3D file.readAll(); QJsonParseError parseError; QJsonDocument project(QJsonDocument::fromJson(jsonData, &parseError)); + if (parseError.error !=3D QJsonParseError::NoError) { return false; } = - /** - * now: get global group - */ QVariantMap globalProject =3D project.toVariant().toMap(); = + return load(globalProject, force); +} + +bool KateProject::loadFromData(const QVariantMap& globalProject, const QSt= ring& directory) +{ + m_baseDir =3D directory; + m_fileName =3D QDir(directory).filePath(QLatin1String(".kateproject")); + return load(globalProject); +} + +bool KateProject::load(const QVariantMap &globalProject, bool force) +{ /** * no name, bad =3D> bail out */ diff --git a/addons/project/kateproject.h b/addons/project/kateproject.h index 4e59106..e400bd0 100644 --- a/addons/project/kateproject.h +++ b/addons/project/kateproject.h @@ -51,11 +51,13 @@ class KateProjectWorkerThread : public QThread public: KateProjectWorkerThread(QObject *worker) : QThread() - , m_worker(worker) { + , m_worker (worker) + { } = protected: - virtual void run() { + virtual void run() + { exec(); delete m_worker; } @@ -84,12 +86,13 @@ public: ~KateProject(); = /** - * Load a project. + * Load a project from project file * Only works once, afterwards use reload(). * @param fileName name of project file * @return success */ - bool load(const QString &fileName); + bool loadFromFile(const QString &fileName); + bool loadFromData(const QVariantMap &globalProject, const QString &dir= ectory); = /** * Try to reload a project. @@ -200,6 +203,8 @@ public: void unregisterDocument(KTextEditor::Document *document); = private Q_SLOTS: + bool load(const QVariantMap &globalProject, bool force =3D false); + /** * Used for worker to send back the results of project loading * @param topLevel new toplevel element for model diff --git a/addons/project/kateprojectconfigpage.cpp b/addons/project/kate= projectconfigpage.cpp new file mode 100644 index 0000000..79962e3 --- /dev/null +++ b/addons/project/kateprojectconfigpage.cpp @@ -0,0 +1,109 @@ +/* This file is part of the KDE project + + 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 Licen= se + 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. +*/ + +#include "kateprojectconfigpage.h" +#include "kateprojectplugin.h" + +#include +#include +#include +#include +#include + +KateProjectConfigPage::KateProjectConfigPage(QWidget *parent, KateProjectP= lugin *plugin) + : KTextEditor::ConfigPage(parent) + , m_plugin(plugin) + , m_changed(false) +{ + QVBoxLayout *layout =3D new QVBoxLayout(this); + layout->setMargin(0); + + QVBoxLayout *vbox =3D new QVBoxLayout; + QGroupBox *group =3D new QGroupBox(i18n("Autoload repositories"), this= ); + group->setWhatsThis(i18n( + "Project plugin is able to autoload repository working copies in c= ase" + "there is .kateproject file already defined")); + + m_cbAutoGit =3D new QCheckBox(i18n("&Git"), this); + vbox->addWidget(m_cbAutoGit); + + m_cbAutoSubversion =3D new QCheckBox(i18n("&Subversion"), this); + vbox->addWidget(m_cbAutoSubversion); + m_cbAutoMercurial =3D new QCheckBox(i18n("&Mercurial"), this); + vbox->addWidget(m_cbAutoMercurial); + + vbox->addStretch(1); + group->setLayout(vbox); + + layout->addWidget(group); + layout->insertStretch(-1, 10); + + reset(); + + connect(m_cbAutoGit, SIGNAL(stateChanged(int)), this, SLOT(slotMyChang= ed())); + connect(m_cbAutoSubversion, SIGNAL(stateChanged(int)), this, SLOT(slot= MyChanged())); + connect(m_cbAutoMercurial, SIGNAL(stateChanged(int)), this, SLOT(slotM= yChanged())); +} + +QString KateProjectConfigPage::name() const +{ + return QString(i18n("Projects")); +} + +QString KateProjectConfigPage::fullName() const +{ + return QString(i18n("Projects properties")); +} + +QIcon KateProjectConfigPage::icon() const +{ + return QIcon::fromTheme(QLatin1String("view-list-tree")); +} + +void KateProjectConfigPage::apply() +{ + if (!m_changed) { + return; + } + + m_changed =3D false; + + m_plugin->setAutoRepository( + m_cbAutoGit->checkState() =3D=3D Qt::Checked, + m_cbAutoSubversion->checkState() =3D=3D Qt::Checked, + m_cbAutoMercurial->checkState() =3D=3D Qt::Checked); +} + +void KateProjectConfigPage::reset() +{ + m_cbAutoGit->setCheckState(m_plugin->autoGit() ? Qt::Checked : Qt::Unc= hecked); + m_cbAutoSubversion->setCheckState(m_plugin->autoSubversion() ? Qt::Che= cked : Qt::Unchecked); + m_cbAutoMercurial->setCheckState(m_plugin->autoMercurial() ? Qt::Check= ed : Qt::Unchecked); + m_changed =3D false; +} + +void KateProjectConfigPage::defaults() +{ + reset(); +} + +void KateProjectConfigPage::slotMyChanged() +{ + m_changed =3D true; + emit changed(); +} diff --git a/addons/project/kateprojectconfigpage.h b/addons/project/katepr= ojectconfigpage.h new file mode 100644 index 0000000..9e97b60 --- /dev/null +++ b/addons/project/kateprojectconfigpage.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + + 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 Licen= se + 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. +*/ + +#ifndef KATE_PROJECT_CONFIGPAGE_H +#define KATE_PROJECT_CONFIGPAGE_H + +#include + +class KateProjectPlugin; +class QWidget; +class QCheckBox; + +class KateProjectConfigPage : public KTextEditor::ConfigPage +{ + Q_OBJECT +public: + explicit KateProjectConfigPage(QWidget *parent =3D nullptr, KateProjec= tPlugin *plugin =3D nullptr); + ~KateProjectConfigPage() {}; + + virtual QString name() const; + virtual QString fullName() const; + virtual QIcon icon() const; + +public Q_SLOTS: + void apply(); + void defaults(); + void reset(); + +private Q_SLOTS: + void slotMyChanged(); + +private: + QCheckBox *m_cbAutoGit; + QCheckBox *m_cbAutoSubversion; + QCheckBox *m_cbAutoMercurial; + KateProjectPlugin *m_plugin; + bool m_changed; +}; + +#endif /* KATE_PROJECT_CONFIGPAGE_H */ diff --git a/addons/project/kateprojectplugin.cpp b/addons/project/kateproj= ectplugin.cpp index a15489b..4832352 100644 --- a/addons/project/kateprojectplugin.cpp +++ b/addons/project/kateprojectplugin.cpp @@ -22,12 +22,16 @@ #include "kateprojectplugin.moc" = #include "kateproject.h" +#include "kateprojectconfigpage.h" #include "kateprojectpluginview.h" = #include #include #include = +#include +#include + #include #include = @@ -43,12 +47,22 @@ = namespace { -const QString ProjectFileName =3D QLatin1String(".kateproject"); +const QString ProjectFileName =3D QStringLiteral(".kateproject"); +const QString GitFolderName =3D QStringLiteral(".git"); +const QString SubversionFolderName =3D QStringLiteral(".svn"); +const QString MercurialFolderName =3D QStringLiteral(".hg"); + +const QString GitConfig =3D QStringLiteral("git"); +const QString SubversionConfig =3D QStringLiteral("subversion"); +const QString MercurialConfig =3D QStringLiteral("mercurial"); + +const QStringList DefaultConfig =3D QStringList() << GitConfig << Subversi= onConfig << MercurialConfig; } = KateProjectPlugin::KateProjectPlugin(QObject *parent, const QList &) : KTextEditor::Plugin(parent) , m_completion(this) + , m_autoGit(true) { qRegisterMetaType("KateProjectSharedQS= tandardItem"); qRegisterMetaType("KateProjectSharedQ= MapStringItem"); @@ -72,6 +86,8 @@ KateProjectPlugin::KateProjectPlugin(QObject *parent, con= st QList &) } #endif = + readConfig(); + foreach(KTextEditor::Document * document, KTextEditor::Editor::instanc= e()->application()->documents()) { slotDocumentCreated(document); } @@ -91,11 +107,24 @@ QObject *KateProjectPlugin::createView(KTextEditor::Ma= inWindow *mainWindow) return new KateProjectPluginView(this, mainWindow); } = +int KateProjectPlugin::configPages() const +{ + return 1; +} + +KTextEditor::ConfigPage *KateProjectPlugin::configPage(int number, QWidget= *parent) +{ + if (number !=3D 0) { + return 0; + } + return new KateProjectConfigPage(parent, this); +} + KateProject *KateProjectPlugin::createProjectForFileName(const QString &fi= leName) { KateProject *project =3D new KateProject(); = - if (!project->load(fileName)) { + if (!project->loadFromFile(fileName)) { delete project; return 0; } @@ -135,6 +164,11 @@ KateProject *KateProjectPlugin::projectForDir(QDir dir) return createProjectForFileName(canonicalFileName); } = + KateProject *project; + if ((project =3D detectGit(dir)) || (project =3D detectSubversion(= dir)) || (project =3D detectMercurial(dir))) { + return project; + } + /** * else: cd up, if possible or abort */ @@ -201,3 +235,110 @@ void KateProjectPlugin::slotDirectoryChanged(const QS= tring &path) } } } + +KateProject* KateProjectPlugin::detectGit(const QDir &dir) +{ + + if (m_autoGit && dir.exists(GitFolderName) && QFileInfo(dir, GitFolder= Name).isDir()) { + return createProjectForRepository(QStringLiteral("git"), dir); + } + + return nullptr; +} + +KateProject* KateProjectPlugin::detectSubversion(const QDir &dir) +{ + if (m_autoSubversion && dir.exists(SubversionFolderName) && QFileInfo(= dir, SubversionFolderName).isDir()) { + return createProjectForRepository(QStringLiteral("svn"), dir); + } + + return nullptr; +} + +KateProject* KateProjectPlugin::detectMercurial(const QDir &dir) +{ + if (m_autoMercurial && dir.exists(MercurialFolderName) && QFileInfo(di= r, MercurialFolderName).isDir()) { + return createProjectForRepository(QStringLiteral("hg"), dir); + } + + return nullptr; +} + +KateProject *KateProjectPlugin::createProjectForRepository(const QString &= type, const QDir &dir) +{ + QVariantMap cnf, files; + files[type] =3D 1; + cnf[QLatin1String("name")] =3D dir.dirName(); + cnf[QLatin1String("files")] =3D (QVariantList() << files); + + KateProject *project =3D new KateProject (); + project->loadFromData(cnf, dir.canonicalPath()); + + m_projects.append(project); + + emit projectCreated(project); + return project; +} + +void KateProjectPlugin::setAutoRepository(bool onGit, bool onSubversion, b= ool onMercurial) +{ + m_autoGit =3D onGit; + m_autoSubversion =3D onSubversion; + m_autoMercurial =3D onMercurial; + writeConfig(); +} + +bool KateProjectPlugin::autoGit() const +{ + return m_autoGit; +} + +bool KateProjectPlugin::autoSubversion() const +{ + return m_autoSubversion; +} + +bool KateProjectPlugin::autoMercurial() const +{ + return m_autoMercurial; +} + +void KateProjectPlugin::readConfig() +{ + KConfigGroup config(KSharedConfig::openConfig(), "project"); + QStringList autorepository =3D config.readEntry("autorepository", Defa= ultConfig); + + m_autoGit =3D m_autoSubversion =3D m_autoMercurial =3D false; + + if (autorepository.contains(GitConfig)) { + m_autoGit =3D true; + } + + if (autorepository.contains(SubversionConfig)) { + m_autoSubversion =3D true; + } + + if (autorepository.contains(MercurialConfig)) { + m_autoMercurial =3D true; + } +} + +void KateProjectPlugin::writeConfig() +{ + KConfigGroup config(KSharedConfig::openConfig(), "project"); + QStringList repos; + + if (m_autoGit) { + repos << GitConfig; + } + + if (m_autoSubversion) { + repos << SubversionConfig; + } + + if (m_autoMercurial) { + repos << MercurialConfig; + } + + config.writeEntry("autorepository", repos); +} diff --git a/addons/project/kateprojectplugin.h b/addons/project/kateprojec= tplugin.h index 2317935..3af12b1 100644 --- a/addons/project/kateprojectplugin.h +++ b/addons/project/kateprojectplugin.h @@ -43,6 +43,9 @@ public: = QObject *createView(KTextEditor::MainWindow *mainWindow); = + virtual int configPages() const; + virtual KTextEditor::ConfigPage *configPage (int number =3D 0, QWidget= *parent =3D 0); + /** * Create new project for given project filename. * Null pointer if no project can be opened. @@ -95,6 +98,11 @@ public: return m_document2Project.value(document); } = + void setAutoRepository(bool onGit, bool onSubversion, bool onMercurial= ); + bool autoGit() const; + bool autoSubversion() const; + bool autoMercurial() const; + Q_SIGNALS: /** * Signal that a new project got created. @@ -127,6 +135,15 @@ public Q_SLOTS: void slotDirectoryChanged(const QString &path); = private: + KateProject *createProjectForRepository(const QString &type, const QDi= r &dir); + KateProject *detectGit(const QDir &dir); + KateProject *detectSubversion(const QDir &dir); + KateProject *detectMercurial(const QDir &dir); + + void readConfig(); + void writeConfig(); + +private: /** * open plugins, maps project base directory =3D> project */ @@ -147,6 +164,10 @@ private: * Project completion */ KateProjectCompletion m_completion; + + bool m_autoGit : 1; + bool m_autoSubversion : 1; + bool m_autoMercurial : 1; }; = #endif