kde-extraapps/kdevplatform/plugins/subversion/kdevsvnplugin.cpp

521 lines
17 KiB
C++
Raw Normal View History

/***************************************************************************
* Copyright 2007 Dukju Ahn <dukjuahn@gmail.com> *
* Copyright 2008 Andreas Pakulat <apaku@gmx.de> *
* *
* 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) any later version. *
* *
***************************************************************************/
#include "kdevsvnplugin.h"
#include <QAction>
#include <QVariant>
#include <QTextStream>
#include <QMenu>
#include <kparts/part.h>
#include <kparts/partmanager.h>
#include <kparts/mainwindow.h>
#include <kaboutdata.h>
#include <ktexteditor/document.h>
#include <ktexteditor/markinterface.h>
#include <kpluginfactory.h>
#include <kpluginloader.h>
#include <klocale.h>
#include <kurlrequester.h>
#include <kaction.h>
#include <kurlrequesterdialog.h>
#include <kfile.h>
#include <ktemporaryfile.h>
#include <kmessagebox.h>
#include <kfiledialog.h>
#include <interfaces/iuicontroller.h>
#include <interfaces/idocumentcontroller.h>
#include <interfaces/idocument.h>
#include <interfaces/iplugincontroller.h>
#include <interfaces/icore.h>
#include <interfaces/iruncontroller.h>
#include <project/projectmodel.h>
#include <interfaces/context.h>
#include <interfaces/contextmenuextension.h>
#include <vcs/vcsrevision.h>
#include <vcs/vcsevent.h>
#include <vcs/vcsstatusinfo.h>
#include <vcs/vcsannotation.h>
#include <vcs/widgets/vcseventwidget.h>
#include <vcs/widgets/vcsdiffwidget.h>
#include <vcs/widgets/vcscommitdialog.h>
#include <language/interfaces/editorcontext.h>
#include "kdevsvncpp/apr.hpp"
#include "svncommitjob.h"
#include "svnstatusjob.h"
#include "svnaddjob.h"
#include "svnrevertjob.h"
#include "svnremovejob.h"
#include "svnupdatejob.h"
#include "svninfojob.h"
#include "svndiffjob.h"
#include "svncopyjob.h"
#include "svnmovejob.h"
#include "svnlogjob.h"
#include "svnblamejob.h"
#include "svnimportjob.h"
#include "svncheckoutjob.h"
#include "svnimportmetadatawidget.h"
#include "svncheckoutmetadatawidget.h"
#include <vcs/vcspluginhelper.h>
#include <vcs/widgets/standardvcslocationwidget.h>
#include "svnlocationwidget.h"
K_PLUGIN_FACTORY(KDevSvnFactory, registerPlugin<KDevSvnPlugin>();)
K_EXPORT_PLUGIN(KDevSvnFactory(KAboutData("kdevsubversion", "kdevsubversion", ki18n("Subversion"), "0.1", ki18n("Support for Subversion version control systems"), KAboutData::License_GPL)))
KDevSvnPlugin::KDevSvnPlugin(QObject *parent, const QVariantList &)
: KDevelop::IPlugin(KDevSvnFactory::componentData(), parent)
, m_common(new KDevelop::VcsPluginHelper(this, this)),
copy_action( 0 ), move_action( 0 )
{
KDEV_USE_EXTENSION_INTERFACE(KDevelop::IBasicVersionControl)
KDEV_USE_EXTENSION_INTERFACE(KDevelop::ICentralizedVersionControl)
qRegisterMetaType<KDevelop::VcsStatusInfo>();
qRegisterMetaType<SvnInfoHolder>();
qRegisterMetaType<KDevelop::VcsEvent>();
qRegisterMetaType<KDevelop::VcsRevision>();
qRegisterMetaType<KDevelop::VcsRevision::RevisionSpecialType>();
qRegisterMetaType<KDevelop::VcsAnnotation>();
qRegisterMetaType<KDevelop::VcsAnnotationLine>();
}
KDevSvnPlugin::~KDevSvnPlugin()
{
}
bool KDevSvnPlugin::isVersionControlled(const KUrl& localLocation)
{
///TODO: also check this in the other functions?
if (!localLocation.isValid()) {
return false;
}
SvnInfoJob* job = new SvnInfoJob(this);
job->setLocation(localLocation);
if (job->exec()) {
QVariant result = job->fetchResults();
if (result.isValid()) {
SvnInfoHolder h = qvariant_cast<SvnInfoHolder>(result);
return !h.name.isEmpty();
}
} else {
kDebug(9510) << "Couldn't execute job";
}
return false;
}
KDevelop::VcsJob* KDevSvnPlugin::repositoryLocation(const KUrl& localLocation)
{
SvnInfoJob* job = new SvnInfoJob(this);
job->setLocation(localLocation);
job->setProvideInformation(SvnInfoJob::RepoUrlOnly);
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::status(const KUrl::List& localLocations,
KDevelop::IBasicVersionControl::RecursionMode mode)
{
SvnStatusJob* job = new SvnStatusJob(this);
job->setLocations(localLocations);
job->setRecursive((mode == KDevelop::IBasicVersionControl::Recursive));
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::add(const KUrl::List& localLocations,
KDevelop::IBasicVersionControl::RecursionMode recursion)
{
SvnAddJob* job = new SvnAddJob(this);
job->setLocations(localLocations);
job->setRecursive((recursion == KDevelop::IBasicVersionControl::Recursive));
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::remove(const KUrl::List& localLocations)
{
SvnRemoveJob* job = new SvnRemoveJob(this);
job->setLocations(localLocations);
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::edit(const KUrl& /*localLocation*/)
{
return 0;
}
KDevelop::VcsJob* KDevSvnPlugin::unedit(const KUrl& /*localLocation*/)
{
return 0;
}
KDevelop::VcsJob* KDevSvnPlugin::localRevision(const KUrl& localLocation, KDevelop::VcsRevision::RevisionType type)
{
SvnInfoJob* job = new SvnInfoJob(this);
job->setLocation(localLocation);
job->setProvideInformation(SvnInfoJob::RevisionOnly);
job->setProvideRevisionType(type);
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::copy(const KUrl& localLocationSrc, const KUrl& localLocationDstn)
{
SvnCopyJob* job = new SvnCopyJob(this);
job->setSourceLocation(localLocationSrc);
job->setDestinationLocation(localLocationDstn);
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::move(const KUrl& localLocationSrc, const KUrl& localLocationDst)
{
SvnMoveJob* job = new SvnMoveJob(this);
job->setSourceLocation(localLocationSrc);
job->setDestinationLocation(localLocationDst);
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::revert(const KUrl::List& localLocations,
KDevelop::IBasicVersionControl::RecursionMode recursion)
{
SvnRevertJob* job = new SvnRevertJob(this);
job->setLocations(localLocations);
job->setRecursive((recursion == KDevelop::IBasicVersionControl::Recursive));
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::update(const KUrl::List& localLocations,
const KDevelop::VcsRevision& rev,
KDevelop::IBasicVersionControl::RecursionMode recursion)
{
SvnUpdateJob* job = new SvnUpdateJob(this);
job->setLocations(localLocations);
job->setRevision(rev);
job->setRecursive((recursion == KDevelop::IBasicVersionControl::Recursive));
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::commit(const QString& message, const KUrl::List& localLocations,
KDevelop::IBasicVersionControl::RecursionMode recursion)
{
SvnCommitJob* job = new SvnCommitJob(this);
kDebug(9510) << "Committing locations:" << localLocations << endl;
job->setUrls(localLocations);
job->setCommitMessage(message) ;
job->setRecursive((recursion == KDevelop::IBasicVersionControl::Recursive));
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::diff(const KUrl& fileOrDirectory,
const KDevelop::VcsRevision& srcRevision,
const KDevelop::VcsRevision& dstRevision,
KDevelop::VcsDiff::Type diffType,
KDevelop::IBasicVersionControl::RecursionMode recurse)
{
KDevelop::VcsLocation loc(fileOrDirectory);
return diff2(loc, loc, srcRevision, dstRevision, diffType, recurse);
}
KDevelop::VcsJob* KDevSvnPlugin::diff2(const KDevelop::VcsLocation& src,
const KDevelop::VcsLocation& dst,
const KDevelop::VcsRevision& srcRevision,
const KDevelop::VcsRevision& dstRevision,
KDevelop::VcsDiff::Type diffType,
KDevelop::IBasicVersionControl::RecursionMode recurse)
{
SvnDiffJob* job = new SvnDiffJob(this);
job->setSource(src);
job->setDestination(dst);
job->setSrcRevision(srcRevision);
job->setDstRevision(dstRevision);
job->setDiffType(diffType);
job->setRecursive((recurse == KDevelop::IBasicVersionControl::Recursive));
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::log(const KUrl& localLocation, const KDevelop::VcsRevision& rev, unsigned long limit)
{
SvnLogJob* job = new SvnLogJob(this);
job->setLocation(localLocation);
job->setStartRevision(rev);
job->setLimit(limit);
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::log(const KUrl& localLocation,
const KDevelop::VcsRevision& startRev,
const KDevelop::VcsRevision& endRev)
{
SvnLogJob* job = new SvnLogJob(this);
job->setLocation(localLocation);
job->setStartRevision(startRev);
job->setEndRevision(endRev);
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::annotate(const KUrl& localLocation,
const KDevelop::VcsRevision& rev)
{
SvnBlameJob* job = new SvnBlameJob(this);
job->setLocation(localLocation);
job->setEndRevision(rev);
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::merge(const KDevelop::VcsLocation& localOrRepoLocationSrc,
const KDevelop::VcsLocation& localOrRepoLocationDst,
const KDevelop::VcsRevision& srcRevision,
const KDevelop::VcsRevision& dstRevision,
const KUrl& localLocation)
{
// TODO implement merge
Q_UNUSED(localOrRepoLocationSrc)
Q_UNUSED(localOrRepoLocationDst)
Q_UNUSED(srcRevision)
Q_UNUSED(dstRevision)
Q_UNUSED(localLocation)
return 0;
}
KDevelop::VcsJob* KDevSvnPlugin::resolve(const KUrl::List& /*localLocations*/,
KDevelop::IBasicVersionControl::RecursionMode /*recursion*/)
{
return 0;
}
KDevelop::VcsJob* KDevSvnPlugin::import(const QString & commitMessage, const KUrl & sourceDirectory, const KDevelop::VcsLocation & destinationRepository)
{
SvnImportJob* job = new SvnImportJob(this);
job->setMapping(sourceDirectory, destinationRepository);
job->setMessage(commitMessage);
return job;
}
KDevelop::VcsJob* KDevSvnPlugin::createWorkingCopy(const KDevelop::VcsLocation & sourceRepository, const KUrl & destinationDirectory, KDevelop::IBasicVersionControl::RecursionMode recursion)
{
SvnCheckoutJob* job = new SvnCheckoutJob(this);
job->setMapping(sourceRepository, destinationDirectory, recursion);
return job;
}
KDevelop::ContextMenuExtension KDevSvnPlugin::contextMenuExtension(KDevelop::Context* context)
{
m_common->setupFromContext(context);
const KUrl::List & ctxUrlList = m_common->contextUrlList();
bool hasVersionControlledEntries = false;
foreach(const KUrl &url, ctxUrlList) {
if (isVersionControlled(url) || isVersionControlled(url.upUrl())) {
hasVersionControlledEntries = true;
break;
}
}
kDebug() << "version controlled?" << hasVersionControlledEntries;
if (!hasVersionControlledEntries)
return IPlugin::contextMenuExtension(context);
QMenu* svnmenu= m_common->commonActions();
svnmenu->addSeparator();
if( !copy_action )
{
copy_action = new KAction(i18n("Copy..."), this);
connect(copy_action, SIGNAL(triggered()), this, SLOT(ctxCopy()));
}
svnmenu->addAction(copy_action);
if( !move_action )
{
move_action = new KAction(i18n("Move..."), this);
connect(move_action, SIGNAL(triggered()), this, SLOT(ctxMove()));
}
svnmenu->addAction(move_action);
KDevelop::ContextMenuExtension menuExt;
menuExt.addAction(KDevelop::ContextMenuExtension::VcsGroup, svnmenu->menuAction());
return menuExt;
}
void KDevSvnPlugin::ctxInfo()
{
KUrl::List const & ctxUrlList = m_common->contextUrlList();
if (ctxUrlList.count() != 1) {
KMessageBox::error(0, i18n("Please select only one item for this operation"));
return;
}
}
void KDevSvnPlugin::ctxStatus()
{
KUrl::List const & ctxUrlList = m_common->contextUrlList();
if (ctxUrlList.count() > 1) {
KMessageBox::error(0, i18n("Please select only one item for this operation"));
return;
}
}
void KDevSvnPlugin::ctxCopy()
{
KUrl::List const & ctxUrlList = m_common->contextUrlList();
if (ctxUrlList.count() > 1) {
KMessageBox::error(0, i18n("Please select only one item for this operation"));
return;
}
KUrl source = ctxUrlList.first();
if (source.isLocalFile()) {
QString dir = source.toLocalFile();
bool isFile = QFileInfo(source.toLocalFile()).isFile();
if (isFile) {
dir = source.directory();
}
KUrlRequesterDialog dlg(dir, i18n("Destination file/directory"), 0);
if (isFile) {
dlg.urlRequester()->setMode(KFile::File | KFile::Directory | KFile::LocalOnly);
} else {
dlg.urlRequester()->setMode(KFile::Directory | KFile::LocalOnly);
}
if (dlg.exec() == QDialog::Accepted) {
KDevelop::ICore::self()->runController()->registerJob(copy(source, dlg.selectedUrl()));
}
} else {
KMessageBox::error(0, i18n("Copying only works on local files"));
return;
}
}
void KDevSvnPlugin::ctxMove()
{
KUrl::List const & ctxUrlList = m_common->contextUrlList();
if (ctxUrlList.count() != 1) {
KMessageBox::error(0, i18n("Please select only one item for this operation"));
return;
}
KUrl source = ctxUrlList.first();
if (source.isLocalFile()) {
QString dir = source.toLocalFile();
bool isFile = QFileInfo(source.toLocalFile()).isFile();
if (isFile) {
dir = source.directory();
}
KUrlRequesterDialog dlg(dir, i18n("Destination file/directory"), 0);
dlg.fileDialog()->setOperationMode( KFileDialog::Saving );
if (isFile) {
dlg.urlRequester()->setMode(KFile::File | KFile::Directory | KFile::LocalOnly);
} else {
dlg.urlRequester()->setMode(KFile::Directory | KFile::LocalOnly);
}
if (dlg.exec() == QDialog::Accepted) {
KDevelop::ICore::self()->runController()->registerJob(move(source, dlg.selectedUrl()));
}
} else {
KMessageBox::error(0, i18n("Moving only works on local files/dirs"));
return;
}
}
void KDevSvnPlugin::ctxCat()
{
KUrl::List const & ctxUrlList = m_common->contextUrlList();
if (ctxUrlList.count() != 1) {
KMessageBox::error(0, i18n("Please select only one item for this operation"));
return;
}
}
QString KDevSvnPlugin::name() const
{
return i18n("Subversion");
}
KDevelop::VcsImportMetadataWidget* KDevSvnPlugin::createImportMetadataWidget(QWidget* parent)
{
return new SvnImportMetadataWidget(parent);
}
void KDevSvnPlugin::ctxImport()
{
KUrl::List const & ctxUrlList = m_common->contextUrlList();
if (ctxUrlList.count() != 1) {
KMessageBox::error(0, i18n("Please select only one item for this operation"));
return;
}
KDialog dlg;
dlg.setCaption(i18n("Import into Subversion repository"));
SvnImportMetadataWidget* widget = new SvnImportMetadataWidget(&dlg);
widget->setSourceLocation(KDevelop::VcsLocation(ctxUrlList.first()));
widget->setSourceLocationEditable(false);
dlg.setMainWidget(widget);
if (dlg.exec() == QDialog::Accepted) {
KDevelop::ICore::self()->runController()->registerJob(import(widget->message(), widget->source(), widget->destination()));
}
}
void KDevSvnPlugin::ctxCheckout()
{
KUrl::List const & ctxUrlList = m_common->contextUrlList();
if (ctxUrlList.count() != 1) {
KMessageBox::error(0, i18n("Please select only one item for this operation"));
return;
}
KDialog dlg;
dlg.setCaption(i18n("Checkout from Subversion repository"));
SvnCheckoutMetadataWidget* widget = new SvnCheckoutMetadataWidget(&dlg);
KUrl tmp = ctxUrlList.first();
tmp.cd("..");
widget->setDestinationLocation(tmp);
dlg.setMainWidget(widget);
if (dlg.exec() == QDialog::Accepted) {
KDevelop::ICore::self()->runController()->registerJob(createWorkingCopy(widget->source(), widget->destination(), widget->recursionMode()));
}
}
KDevelop::VcsLocationWidget* KDevSvnPlugin::vcsLocation(QWidget* parent) const
{
return new SvnLocationWidget(parent);
}
#include "moc_kdevsvnplugin.cpp"