mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-24 19:02:53 +00:00
520 lines
17 KiB
C++
520 lines
17 KiB
C++
/***************************************************************************
|
|
* 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"
|