1 /***************************************************************************
2 * This file was partly taken from KDevelop's cvs plugin *
3 * Copyright 2007 Robert Gruber <rgruber@users.sourceforge.net> *
5 * Adapted for DVCS (added templates) *
6 * Copyright 2008 Evgeniy Ivanov <powerfox@kde.ru> *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation; either version 2 of *
11 * the License or (at your option) version 3 or any later version *
12 * accepted by the membership of KDE e.V. (or its successor approved *
13 * by the membership of KDE e.V.), which shall act as a proxy *
14 * defined in Section 14 of version 3 of the license. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
23 ***************************************************************************/
25 #ifndef DVCS_PLUGIN_CC
26 #define DVCS_PLUGIN_CC
28 #include "dvcsplugin.h"
30 #include <QtGui/QAction>
31 #include <QtGui/QMenu>
32 #include <QtCore/QFileInfo>
33 #include <QtCore/QDir>
37 #include <KParts/PartManager>
38 #include <KParts/Part>
40 #include <KActionCollection>
41 #include <KMessageBox>
44 #include <interfaces/iproject.h>
45 #include <project/projectmodel.h>
46 #include <interfaces/iuicontroller.h>
47 #include <interfaces/iruncontroller.h>
48 #include <interfaces/iprojectcontroller.h>
49 #include <interfaces/icore.h>
50 #include <interfaces/context.h>
51 #include<interfaces/contextmenuextension.h>
53 #include "../vcsmapping.h"
54 #include "../vcsjob.h"
56 #include "ui/dvcsmainview.h"
57 #include "ui/dvcsgenericoutputview.h"
58 #include "ui/importdialog.h"
59 #include "ui/importmetadatawidget.h"
60 #include "ui/logview.h"
61 #include "ui/branchmanager.h"
62 #include "ui/commitmanager.h"
63 #include "ui/revhistory/commitlogmodel.h"
64 #include "ui/revhistory/commitView.h"
66 using KDevelop::DistributedVersionControlPlugin
;
69 //class DistributedVersionControlPlugin
70 DistributedVersionControlPlugin::DistributedVersionControlPlugin(QObject
*parent
, KComponentData compData
)
71 :IPlugin(compData
, parent
), d(new DistributedVersionControlPluginPrivate())
73 QString EasterEgg
= i18n("Horses are forbidden to eat fire hydrants in Marshalltown, Iowa.");
75 d
->m_factory
= new KDevDVCSViewFactory(this);
78 // Begin: KDevelop::IBasicVersionControl
80 QString
DistributedVersionControlPlugin::name() const
82 return d
->m_exec
->name();
85 bool DistributedVersionControlPlugin::isVersionControlled(const KUrl
& localLocation
)
87 //TODO: some files from repository location can be not version controlled
88 kDebug() << "checking version controlled with executor:" << d
->m_exec
->name();
89 return d
->m_exec
->isValidDirectory(localLocation
);
93 DistributedVersionControlPlugin::repositoryLocation(const KUrl
& localLocation
)
95 Q_UNUSED(localLocation
)
99 //Note: recursion is not used
102 DistributedVersionControlPlugin::add(const KUrl::List
& localLocations
,
103 IBasicVersionControl::RecursionMode recursion
)
106 ///TODO: why do we send localLocations twice? In most cases [0] is a repo pass and an dir item to add path
107 return d
->m_exec
->add(localLocations
[0].path(), localLocations
);
111 DistributedVersionControlPlugin::remove(const KUrl::List
& localLocations
)
113 QFileInfo
info(localLocations
[0].toLocalFile() );
115 return d
->m_exec
->remove(info
.absolutePath(), localLocations
);
119 DistributedVersionControlPlugin::status(const KUrl::List
& localLocations
,
120 IBasicVersionControl::RecursionMode recursion
)
122 QFileInfo
info( localLocations
[0].toLocalFile() );
124 return d
->m_exec
->status(info
.absolutePath(),
126 (recursion
== IBasicVersionControl::Recursive
) ? true:false);
131 DistributedVersionControlPlugin::copy(const KUrl
& localLocationSrc
,
132 const KUrl
& localLocationDstn
)
134 Q_UNUSED(localLocationSrc
)
135 Q_UNUSED(localLocationDstn
)
136 return d
->m_exec
->empty_cmd();
141 DistributedVersionControlPlugin::move(const KUrl
& localLocationSrc
,
142 const KUrl
& localLocationDst
)
144 Q_UNUSED(localLocationSrc
)
145 Q_UNUSED(localLocationDst
)
146 return d
->m_exec
->empty_cmd();
150 DistributedVersionControlPlugin::revert(const KUrl::List
& localLocations
,
151 IBasicVersionControl::RecursionMode recursion
)
153 Q_UNUSED(localLocations
)
155 return d
->m_exec
->empty_cmd();
159 DistributedVersionControlPlugin::update(const KUrl::List
& localLocations
, const VcsRevision
& rev
,
160 IBasicVersionControl::RecursionMode recursion
)
162 Q_UNUSED(localLocations
)
165 return d
->m_exec
->empty_cmd();
169 DistributedVersionControlPlugin::commit(const QString
& message
, const KUrl::List
& localLocations
,
170 IBasicVersionControl::RecursionMode recursion
)
172 //used by appwizard plugin only (and maybe something that opens a project)
174 QString msg
= message
;
176 return d
->m_exec
->commit(localLocations
[0].path(), msg
, localLocations
);
180 DistributedVersionControlPlugin::diff(const VcsLocation
& localOrRepoLocationSrc
,
181 const VcsLocation
& localOrRepoLocationDst
,
182 const VcsRevision
& srcRevision
,
183 const VcsRevision
& dstRevision
,
184 VcsDiff::Type
, IBasicVersionControl::RecursionMode
)
186 Q_UNUSED(localOrRepoLocationSrc
)
187 Q_UNUSED(localOrRepoLocationDst
)
188 Q_UNUSED(srcRevision
)
189 Q_UNUSED(dstRevision
)
191 return d
->m_exec
->empty_cmd();
195 DistributedVersionControlPlugin::log(const KUrl
& localLocation
,
196 const VcsRevision
& rev
,
197 unsigned long limit
)
199 Q_UNUSED(localLocation
)
202 return d
->m_exec
->empty_cmd();
206 DistributedVersionControlPlugin::log(const KUrl
& localLocation
,
207 const VcsRevision
& rev
,
208 const VcsRevision
& limit
)
210 Q_UNUSED(localLocation
)
213 return d
->m_exec
->empty_cmd();
217 DistributedVersionControlPlugin::annotate(const KUrl
& localLocation
,
218 const VcsRevision
& rev
)
220 Q_UNUSED(localLocation
)
222 return d
->m_exec
->empty_cmd();
226 DistributedVersionControlPlugin::merge(const VcsLocation
& localOrRepoLocationSrc
,
227 const VcsLocation
& localOrRepoLocationDst
,
228 const VcsRevision
& srcRevision
,
229 const VcsRevision
& dstRevision
,
230 const KUrl
& localLocation
)
232 Q_UNUSED(localOrRepoLocationSrc
)
233 Q_UNUSED(localOrRepoLocationDst
)
234 Q_UNUSED(srcRevision
)
235 Q_UNUSED(dstRevision
)
236 Q_UNUSED(localLocation
)
237 return d
->m_exec
->empty_cmd();
242 DistributedVersionControlPlugin::resolve(const KUrl::List
& localLocations
,
243 IBasicVersionControl::RecursionMode recursion
)
245 Q_UNUSED(localLocations
)
247 return d
->m_exec
->empty_cmd();
250 // End: KDevelop::IBasicVersionControl
253 // Begin: KDevelop::IDistributedVersionControl
256 DistributedVersionControlPlugin::init(const KUrl
& localRepositoryRoot
)
258 Q_UNUSED(localRepositoryRoot
)
259 return d
->m_exec
->init(localRepositoryRoot
);
263 DistributedVersionControlPlugin::clone(const VcsLocation
& localOrRepoLocationSrc
,
264 const KUrl
& localRepositoryRoot
)
266 Q_UNUSED(localOrRepoLocationSrc
)
267 Q_UNUSED(localRepositoryRoot
)
268 return d
->m_exec
->empty_cmd();
272 DistributedVersionControlPlugin::push(const KUrl
& localRepositoryLocation
,
273 const VcsLocation
& localOrRepoLocationDst
)
275 Q_UNUSED(localRepositoryLocation
)
276 Q_UNUSED(localOrRepoLocationDst
)
277 return d
->m_exec
->empty_cmd();
281 DistributedVersionControlPlugin::pull(const VcsLocation
& localOrRepoLocationSrc
,
282 const KUrl
& localRepositoryLocation
)
284 Q_UNUSED(localOrRepoLocationSrc
)
285 Q_UNUSED(localRepositoryLocation
)
286 return d
->m_exec
->empty_cmd();
290 DistributedVersionControlPlugin::checkout(const QString
&localLocation
,
293 return d
->m_exec
->checkout(repo
, localLocation
);
296 // End: KDevelop::IDistributedVersionControl
299 KDevelop::IDVCSexecutor
* DistributedVersionControlPlugin::proxy()
305 KDevelop::VcsImportMetadataWidget
*
306 DistributedVersionControlPlugin::createImportMetadataWidget(QWidget
* parent
)
308 return new ImportMetadataWidget(parent
);
311 const KUrl
DistributedVersionControlPlugin::urlFocusedDocument() const
313 return d
->m_ctxUrlList
.first();
316 KDevelop::ContextMenuExtension
317 DistributedVersionControlPlugin::contextMenuExtension(Context
* context
)
319 KUrl::List ctxUrlList
;
320 if( context
->type() == Context::ProjectItemContext
)
322 ProjectItemContext
*itemCtx
= dynamic_cast<ProjectItemContext
*>(context
);
325 kDebug() << "itemCtx is true";
326 QList
<ProjectBaseItem
*> baseItemList
= itemCtx
->items();
329 foreach( ProjectBaseItem
* _item
, baseItemList
)
331 if( _item
->folder() ){
332 ProjectFolderItem
*folderItem
= dynamic_cast<ProjectFolderItem
*>(_item
);
333 kDebug() << "folderItem->url() is assigned to ctxUrlList"<<folderItem
->url();
334 ctxUrlList
<< folderItem
->url();
336 else if( _item
->file() ){
337 ProjectFileItem
*fileItem
= dynamic_cast<ProjectFileItem
*>(_item
);
338 kDebug() << "fileItem->url() is assigned to ctxUrlList"<<fileItem
->url();
339 ctxUrlList
<< fileItem
->url();
344 else if( context
->type() == Context::EditorContext
)
346 EditorContext
*itemCtx
= dynamic_cast<EditorContext
*>(context
);
347 ctxUrlList
<< itemCtx
->url();
349 else if( context
->type() == Context::FileContext
)
351 FileContext
*itemCtx
= dynamic_cast<FileContext
*>(context
);
352 ctxUrlList
+= itemCtx
->urls();
355 ContextMenuExtension menuExt
;
357 bool hasVersionControlledEntries
= false;
358 foreach(const KUrl
&url
, ctxUrlList
)
360 if(isVersionControlled( url
) )
362 kDebug() << url
<< "is version controller";
363 hasVersionControlledEntries
= true;
367 if(ctxUrlList
.isEmpty() )
368 return IPlugin::contextMenuExtension(context
);
370 DistributedVersionControlPlugin::d
->m_ctxUrlList
= ctxUrlList
;
371 QList
<QAction
*> actions
;
373 kDebug() << "version controlled?" << hasVersionControlledEntries
;
374 QMenu
* menu
= new QMenu(name() );
375 if(hasVersionControlledEntries
)
377 action
= new KAction(i18n("Commit..."), this);
378 connect( action
, SIGNAL(triggered()), this, SLOT(ctxCommit()) );
379 menu
->addAction(action
);
381 action
= new KAction(i18n("Branch Manager"), this);
382 connect( action
, SIGNAL(triggered()), this, SLOT(ctxCheckout()) );
383 menu
->addAction( action
);
385 action
= new KAction(i18n("Revision History"), this);
386 connect( action
, SIGNAL(triggered()), this, SLOT(ctxRevHistory()) );
387 menu
->addAction( action
);
389 action
= new KAction(i18n("Status"), this);
390 connect( action
, SIGNAL(triggered()), this, SLOT(ctxStatus()) );
391 menu
->addAction( action
);
393 action
= new KAction(i18n("Log View"), this);
394 connect( action
, SIGNAL(triggered()), this, SLOT(ctxLog()) );
395 menu
->addAction( action
);
399 action
= new KAction(i18n("Init..."), this);
400 connect( action
, SIGNAL(triggered()), this, SLOT(slotInit()) );
401 menu
->addAction(action
);
403 menuExt
.addAction(ContextMenuExtension::ExtensionGroup
, menu
->menuAction() );
409 void DistributedVersionControlPlugin::slotInit()
411 KUrl url
= urlFocusedDocument();
413 QFileInfo repoInfo
= QFileInfo(url
.path());
414 if (repoInfo
.isFile())
415 url
= repoInfo
.path();
417 ImportDialog
dlg(this, url
);
421 void DistributedVersionControlPlugin::ctxCommit()
423 CommitManager
* cmtManager
= new CommitManager(d
->m_ctxUrlList
.first().path(), proxy());
427 void DistributedVersionControlPlugin::ctxAdd()
429 VcsJob
* j
= add(DistributedVersionControlPlugin::d
->m_ctxUrlList
, IBasicVersionControl::Recursive
);
430 DVCSjob
* job
= dynamic_cast<DVCSjob
*>(j
);
432 connect(job
, SIGNAL(result(KJob
*) ),
433 this, SIGNAL(jobFinished(KJob
*) ));
438 void DistributedVersionControlPlugin::ctxRemove()
440 VcsJob
* j
= remove(DistributedVersionControlPlugin::d
->m_ctxUrlList
);
441 DVCSjob
* job
= dynamic_cast<DVCSjob
*>(j
);
443 connect(job
, SIGNAL( result(KJob
*) ),
444 this, SIGNAL( jobFinished(KJob
*) ));
449 void DistributedVersionControlPlugin::ctxCheckout()
451 BranchManager
*brManager
= new BranchManager(d
->m_ctxUrlList
.first().path(), proxy());
452 connect(brManager
, SIGNAL(checkouted(KJob
*) ),
453 this, SLOT(checkoutFinished(KJob
*) ));
457 void DistributedVersionControlPlugin::ctxLog()
460 VcsJob
* j
= log(d
->m_ctxUrlList
.first(), rev
, 0);
461 DVCSjob
* job
= dynamic_cast<DVCSjob
*>(j
);
463 ICore::self()->runController()->registerJob(job
);
464 LogView
* view
= new LogView(this, job
);
465 emit
addNewTabToMainView( view
, i18n("Log") );
469 void DistributedVersionControlPlugin::ctxStatus()
471 KUrl url
= urlFocusedDocument();
475 KDevelop::VcsJob
* j
= status(url
, KDevelop::IBasicVersionControl::Recursive
);
476 DVCSjob
* job
= dynamic_cast<DVCSjob
*>(j
);
478 DVCSgenericOutputView
* view
= new DVCSgenericOutputView(this, job
);
479 emit
addNewTabToMainView(view
, i18n("Status") );
480 KDevelop::ICore::self()->runController()->registerJob(job
);
484 void DistributedVersionControlPlugin::ctxRevHistory()
486 KUrl url
= urlFocusedDocument();
487 kDebug() << "url is: " << url
.path();
489 CommitLogModel
* model
= new CommitLogModel(proxy()->getAllCommits(url
.path()));
490 CommitView
*revTree
= new CommitView
;
491 revTree
->setModel(model
);
493 emit
addNewTabToMainView(revTree
, i18n("Revision History") );
496 void DistributedVersionControlPlugin::checkoutFinished(KJob
* _checkoutJob
)
498 DVCSjob
* checkoutJob
= dynamic_cast<DVCSjob
*>(_checkoutJob
);
500 kDebug() << "checkout url is: " << KUrl(checkoutJob
->getDirectory() );
501 KDevelop::IProject
* curProject
= core()->projectController()->findProjectForUrl(KUrl(checkoutJob
->getDirectory() ));
505 kDebug() << "couldn't find project for url:" << checkoutJob
->getDirectory();
508 KUrl projectFile
= curProject
->projectFileUrl();
510 core()->projectController()->closeProject(curProject
); //let's ask to save all files!
512 if (!checkoutJob
->exec())
513 kDebug() << "CHECKOUT PROBLEM!";
515 kDebug() << "projectFile is " << projectFile
<< " JobDir is " <<checkoutJob
->getDirectory();
516 kDebug() << "Project will be closed and open";
517 if(!core()->projectController()->openProject(projectFile
))
519 KMessageBox::sorry( 0,
520 i18n( "Could not open project %1.",
521 projectFile
.path() ) );
523 // maybe IProject::reloadModel?
524 // emit jobFinished(_checkoutJob); //couses crash!
527 //-----------------------------------------------------------------------------------
530 //class KDevDVCSViewFactory
531 QWidget
* KDevDVCSViewFactory::create(QWidget
*parent
)
533 return new DVCSmainView(m_plugin
, parent
);
536 Qt::DockWidgetArea
KDevDVCSViewFactory::defaultPosition()
538 return Qt::BottomDockWidgetArea
;
541 QString
KDevDVCSViewFactory::id() const
543 return "org.kdevelop.DVCSview";