diff --git a/vcs/models/projectchangesmodel.cpp b/vcs/models/projectchangesmodel.cpp index 033846f894..4f60911815 100644 --- a/vcs/models/projectchangesmodel.cpp +++ b/vcs/models/projectchangesmodel.cpp @@ -1,250 +1,272 @@ /* This file is part of KDevelop Copyright 2010 Aleix Pol Gonzalez 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. */ #include "projectchangesmodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include + +Q_DECLARE_METATYPE(KDevelop::IProject*); using namespace KDevelop; ProjectChangesModel::ProjectChangesModel(QObject* parent) : VcsFileChangesModel(parent) { foreach(IProject* p, ICore::self()->projectController()->projects()) addProject(p); connect(ICore::self()->projectController(), SIGNAL(projectOpened(KDevelop::IProject*)), SLOT(addProject(KDevelop::IProject*))); connect(ICore::self()->projectController(), SIGNAL(projectClosing(KDevelop::IProject*)), SLOT(removeProject(KDevelop::IProject*))); connect(ICore::self()->documentController(), SIGNAL(documentSaved(KDevelop::IDocument*)), SLOT(documentSaved(KDevelop::IDocument*))); connect(ICore::self()->projectController()->projectModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(itemsAdded(QModelIndex,int,int))); connect(ICore::self()->runController(), SIGNAL(jobUnregistered(KJob*)), SLOT(jobUnregistered(KJob*))); } ProjectChangesModel::~ProjectChangesModel() {} void ProjectChangesModel::addProject(IProject* p) { QStandardItem* it = new QStandardItem(p->name()); it->setData(p->name(), ProjectChangesModel::ProjectNameRole); - if(p->versionControlPlugin()) { - IPlugin* plugin = p->versionControlPlugin(); - + IPlugin* plugin = p->versionControlPlugin(); + if(plugin) { IBasicVersionControl* vcs = plugin->extension(); KPluginInfo info = ICore::self()->pluginController()->pluginInfo(plugin); it->setIcon(KIcon(info.icon())); it->setToolTip(vcs->name()); reload(QList() << p); IBranchingVersionControl* branchingExtension = plugin->extension(); if(branchingExtension) { branchingExtension->registerRepositoryForCurrentBranchChanges(p->folder()); connect(plugin, SIGNAL(repositoryBranchChanged(KUrl)), this, SLOT(repositoryBranchChanged(KUrl))); repositoryBranchChanged(p->folder()); } } else { it->setEnabled(false); } appendRow(it); } void ProjectChangesModel::removeProject(IProject* p) { QStandardItem* it=projectItem(p); removeRow(it->row()); } QStandardItem* findItemChild(QStandardItem* parent, const QVariant& value, int role = Qt::DisplayRole) { for(int i=0; irowCount(); i++) { QStandardItem* curr=parent->child(i); if(curr->data(role) == value) return curr; } return 0; } QStandardItem* ProjectChangesModel::projectItem(IProject* p) const { return findItemChild(invisibleRootItem(), p->name(), ProjectChangesModel::ProjectNameRole); } -void ProjectChangesModel::addStates(const QVariantList& states) -{ - IProjectController* projectController = ICore::self()->projectController(); - - foreach(const QVariant& state, states) { - VcsStatusInfo st = state.value(); - - IProject* project = projectController->findProjectForUrl(st.url()); - - if(project) - updateState(project, st); - } -} - void ProjectChangesModel::updateState(IProject* p, const KDevelop::VcsStatusInfo& status) { QStandardItem* pItem = projectItem(p); Q_ASSERT(pItem); VcsFileChangesModel::updateState(pItem, status); } void ProjectChangesModel::changes(IProject* project, const KUrl::List& urls, IBasicVersionControl::RecursionMode mode) { IPlugin* vcsplugin=project->versionControlPlugin(); IBasicVersionControl* vcs = vcsplugin ? vcsplugin->extension() : 0; if(vcs && vcs->isVersionControlled(urls.first())) { //TODO: filter? VcsJob* job=vcs->status(urls, mode); + job->setProperty("urls", qVariantFromValue(urls)); + job->setProperty("mode", qVariantFromValue(mode)); + job->setProperty("project", qVariantFromValue(project)); connect(job, SIGNAL(finished(KJob*)), SLOT(statusReady(KJob*))); ICore::self()->runController()->registerJob(job); } } void ProjectChangesModel::statusReady(KJob* job) { VcsJob* status=static_cast(job); - - addStates(status->fetchResults().toList()); + + QList states = status->fetchResults().toList(); + IProject* project = job->property("project").value(); + if(!project) + return; + + QSet foundUrls; + foreach(const QVariant& state, states) { + VcsStatusInfo st = state.value(); + foundUrls += st.url(); + + updateState(project, st); + } + + QStandardItem* itProject = projectItem(project); + + IBasicVersionControl::RecursionMode mode = IBasicVersionControl::RecursionMode(job->property("mode").toInt()); + QSet uncertainUrls = urls(itProject).toSet().subtract(foundUrls); + QList sourceUrls = job->property("urls").value(); + foreach(const KUrl& url, sourceUrls) { + if(url.isLocalFile() && QDir(url.toLocalFile()).exists()) { + foreach(const KUrl& currentUrl, uncertainUrls) { + if((mode == IBasicVersionControl::NonRecursive && currentUrl.upUrl().equals(url, KUrl::CompareWithoutTrailingSlash)) + || (mode == IBasicVersionControl::Recursive && url.isParentOf(currentUrl)) + ) { + QStandardItem* fileItem = fileItemForUrl(itProject, currentUrl); + itProject->removeRow(fileItem->row()); + } + } + } + } } void ProjectChangesModel::documentSaved(KDevelop::IDocument* document) { reload(KUrl::List() << document->url()); } void ProjectChangesModel::itemsAdded(const QModelIndex& parent, int start, int end) { ProjectModel* model=ICore::self()->projectController()->projectModel(); ProjectBaseItem* item=model->itemFromIndex(parent); if(!item) return; IProject* project=item->project(); if(!project) return; KUrl::List urls; for(int i=start; iitemFromIndex(idx); if(item->type()==ProjectBaseItem::File || item->type()==ProjectBaseItem::Folder || item->type()==ProjectBaseItem::BuildFolder) urls += item->url(); } if(!urls.isEmpty()) changes(project, urls, KDevelop::IBasicVersionControl::NonRecursive); } void ProjectChangesModel::reload(const QList& projects) { foreach(IProject* project, projects) changes(project, project->folder(), KDevelop::IBasicVersionControl::Recursive); } void ProjectChangesModel::reload(const QList& urls) { foreach(const KUrl& url, urls) { IProject* project=ICore::self()->projectController()->findProjectForUrl(url); if(project) changes(project, url, KDevelop::IBasicVersionControl::NonRecursive); } } void ProjectChangesModel::reloadAll() { QList< IProject* > projects = ICore::self()->projectController()->projects(); reload(projects); } void ProjectChangesModel::jobUnregistered(KJob* job) { static QList readOnly = QList() << KDevelop::VcsJob::Add << KDevelop::VcsJob::Remove << KDevelop::VcsJob::Pull << KDevelop::VcsJob::Commit << KDevelop::VcsJob::Move << KDevelop::VcsJob::Copy << KDevelop::VcsJob::Revert ; VcsJob* vcsjob=dynamic_cast(job); if(vcsjob && readOnly.contains(vcsjob->type())) { reloadAll(); } } void ProjectChangesModel::repositoryBranchChanged(const KUrl& url) { IProject* project = ICore::self()->projectController()->findProjectForUrl(url); if(project) { IPlugin* v = project->versionControlPlugin(); Q_ASSERT(v); IBranchingVersionControl* branching = v->extension(); Q_ASSERT(branching); VcsJob* job = branching->currentBranch(url); connect(job, SIGNAL(resultsReady(KDevelop::VcsJob*)), SLOT(branchNameReady(KDevelop::VcsJob*))); job->setProperty("project", QVariant::fromValue(project)); ICore::self()->runController()->registerJob(job); } } void ProjectChangesModel::branchNameReady(VcsJob* job) { IProject* project = qobject_cast(job->property("project").value()); if(job->status()==VcsJob::JobSucceeded) { QString branchName = job->fetchResults().toString().isEmpty() ? i18n("no branch") : job->fetchResults().toString(); projectItem(project)->setText(i18nc("project name (branch name)", "%1 (%2)", project->name(), branchName)); } else { projectItem(project)->setText(project->name()); } + + reload(QList() << project); } diff --git a/vcs/models/projectchangesmodel.h b/vcs/models/projectchangesmodel.h index 9546969162..54b112815c 100644 --- a/vcs/models/projectchangesmodel.h +++ b/vcs/models/projectchangesmodel.h @@ -1,67 +1,66 @@ /* This file is part of KDevelop Copyright 2010 Aleix Pol Gonzalez 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. */ #ifndef KDEVPLATFORM_PROJECTCHANGESMODEL_H #define KDEVPLATFORM_PROJECTCHANGESMODEL_H #include #include #include "../vcsexport.h" class KJob; namespace KDevelop { class IProject; class IDocument; class KDEVPLATFORMVCS_EXPORT ProjectChangesModel : public VcsFileChangesModel { Q_OBJECT public: enum Role { ProjectNameRole = Qt::UserRole }; ProjectChangesModel(QObject* parent); virtual ~ProjectChangesModel(); - void addStates(const QVariantList& states); void updateState(KDevelop::IProject* p, const KDevelop::VcsStatusInfo& status); QStandardItem* projectItem(KDevelop::IProject* p) const; static QStandardItem* fileItemForProject(QStandardItem* projectItem, const QUrl& url); void changes(KDevelop::IProject* project, const KUrl::List& urls, KDevelop::IBasicVersionControl::RecursionMode mode); public slots: void reloadAll(); void reload(const QList& p); void reload(const QList& p); void addProject(KDevelop::IProject* p); void removeProject(KDevelop::IProject* p); void statusReady(KJob* job); void documentSaved(KDevelop::IDocument*); void itemsAdded(const QModelIndex& idx, int start, int end); void jobUnregistered(KJob*); void repositoryBranchChanged(const KUrl& url); void branchNameReady(KDevelop::VcsJob* job); }; } #endif // KDEVPLATFORM_PROJECTCHANGESMODEL_H