00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <qdir.h>
00015 #include <qpopupmenu.h>
00016 #include <qwhatsthis.h>
00017
00018 #include <kpopupmenu.h>
00019 #include <kdebug.h>
00020 #include <klocale.h>
00021 #include <kmessagebox.h>
00022 #include <kdialogbase.h>
00023 #include <kstandarddirs.h>
00024 #include <kaction.h>
00025 #include <kurl.h>
00026 #include <kapplication.h>
00027 #include <kmainwindow.h>
00028
00029 #include <kprocess.h>
00030 #include <kiconloader.h>
00031
00032 #include <dcopref.h>
00033 #include <repository_stub.h>
00034 #include <cvsservice_stub.h>
00035 #include <cvsjob_stub.h>
00036
00037 #include <kparts/part.h>
00038 #include <kdevpartcontroller.h>
00039 #include <kdevgenericfactory.h>
00040
00041 #include "kdevcore.h"
00042 #include "kdevmakefrontend.h"
00043 #include "kdevdifffrontend.h"
00044 #include "kdevappfrontend.h"
00045 #include "domutil.h"
00046 #include "kdevmainwindow.h"
00047 #include "kdevproject.h"
00048 #include "urlutil.h"
00049
00050 #include "cvsform.h"
00051 #include "commitdlg.h"
00052 #include "checkoutdialog.h"
00053 #include "tagdialog.h"
00054 #include "cvsprocesswidget.h"
00055 #include "cvsoptions.h"
00056 #include "cvsoptionswidget.h"
00057 #include "cvspartimpl.h"
00058 #include "cvsdir.h"
00059
00060 #include "cvspart.h"
00061
00063
00065
00066
00067 bool g_projectWasJustCreated = false;
00068
00070
00072
00073 static const KAboutData data("kdevcvsservice", I18N_NOOP("CvsService"), "1.0");
00074 typedef KDevGenericFactory<CvsServicePart> CvsFactory;
00075 K_EXPORT_COMPONENT_FACTORY( libkdevcvsservice, CvsFactory( &data ) )
00076
00077
00078
00080
00081 CvsServicePart::CvsServicePart( QObject *parent, const char *name, const QStringList & )
00082 : KDevVersionControl( "KDevCvsServicePart", "cervisia", parent,
00083 name ? name : "CvsService" ),
00084 actionCommit( 0 ), actionDiff( 0 ), actionLog( 0 ), actionAdd( 0 ),
00085 actionAddBinary( 0 ), actionRemove( 0 ), actionUpdate( 0 ),
00086 actionRemoveSticky( 0 ),
00087 actionAddToIgnoreList( 0 ), actionRemoveFromIgnoreList( 0 ),
00088 actionTag( 0 ), actionUnTag( 0 ),
00089 actionLogin( 0), actionLogout( 0 ),
00090 m_impl( 0 )
00091 {
00092 setInstance( CvsFactory::instance() );
00093
00094 init();
00095
00098 setVersionControl( this );
00099 }
00100
00102
00103 CvsServicePart::~CvsServicePart()
00104 {
00105 delete m_cvsConfigurationForm;
00106 delete m_impl;
00107 }
00108
00110
00111 void CvsServicePart::init()
00112 {
00113 setupActions();
00114
00115 m_impl = new CvsServicePartImpl( this );
00116
00117 connect( m_impl, SIGNAL(checkoutFinished(QString)), SIGNAL(finishedFetching(QString)) );
00118
00119
00120 connect( core(), SIGNAL(projectOpened()), this, SLOT(slotProjectOpened()) );
00121 connect( core(), SIGNAL(projectClosed()), this, SLOT(slotProjectClosed()) );
00122
00123
00124 connect( core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)),
00125 this, SLOT(contextMenu(QPopupMenu *, const Context *)) );
00126 connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)),
00127 this, SLOT(projectConfigWidget(KDialogBase*)) );
00128 connect( core(), SIGNAL(stopButtonClicked(KDevPlugin*)),
00129 this, SLOT(slotStopButtonClicked(KDevPlugin*)) );
00130
00131 m_impl->m_widget->setIcon( UserIcon( "kdev_cvs", KIcon::DefaultState, CvsFactory::instance()) );
00132 QWhatsThis::add( m_impl->processWidget(), i18n("<b>CVS</b><p>Concurrent Versions System operations window. Shows output of Cervisia CVS Service.") );
00133 m_impl->processWidget()->setCaption(i18n("CvsService Output"));
00134 mainWindow()->embedOutputView( m_impl->processWidget(), i18n("CvsService"), i18n("cvs output") );
00135 }
00136
00138
00139 void CvsServicePart::setupActions()
00140 {
00141
00142
00143
00144 actionCommit = new KAction( i18n("&Commit to Repository"), 0, this,
00145 SLOT(slotActionCommit()), actionCollection(), "cvsservice_commit" );
00146 actionCommit->setToolTip( i18n("Commit file(s)") );
00147 actionCommit->setWhatsThis( i18n("<b>Commit file(s)</b><p>Commits file to repository if modified.") );
00148
00149 actionDiff = new KAction( i18n("&Difference Between Revisions"), 0, this, SLOT(slotActionDiff()),
00150 actionCollection(), "cvsservice_diff" );
00151 actionDiff->setToolTip( i18n("Build difference") );
00152 actionDiff->setWhatsThis( i18n("<b>Build difference</b><p>Builds difference between releases.") );
00153
00154 actionLog = new KAction( i18n("Generate &Log"), 0, this, SLOT(slotActionLog()),
00155 actionCollection(), "cvsservice_log" );
00156 actionLog->setToolTip( i18n("Generate log") );
00157 actionLog->setWhatsThis( i18n("<b>Generate log</b><p>Produces log for this file.") );
00158
00159 actionAdd = new KAction( i18n("&Add to Repository"), 0, this, SLOT(slotActionAdd()),
00160 actionCollection(), "cvsservice_add" );
00161 actionAdd->setToolTip( i18n("Add file to repository") );
00162 actionAdd->setWhatsThis( i18n("<b>Add to repository</b><p>Adds file to repository.") );
00163
00164 actionAddBinary = new KAction( i18n("Add to Repository as &Binary"), 0, this,
00165 SLOT(slotActionAddBinary()), actionCollection(), "cvsservice_add_bin" );
00166 actionAddBinary->setToolTip( i18n("Add file to repository as binary") );
00167 actionAddBinary->setWhatsThis( i18n("<b>Add to repository as binary</b><p>Adds file to repository as binary (-kb option).") );
00168
00169 actionRemove = new KAction( i18n("&Remove From Repository"), 0, this,
00170 SLOT(slotActionRemove()), actionCollection(), "cvsservice_remove" );
00171 actionRemove->setToolTip( i18n("Remove from repository") );
00172 actionRemove->setWhatsThis( i18n("<b>Remove from repository</b><p>Removes file(s) from repository.") );
00173
00174 actionUpdate = new KAction( i18n("&Update/Revert to Another Release"), 0, this,
00175 SLOT(slotActionUpdate()), actionCollection(), "cvsservice_update" );
00176 actionUpdate->setToolTip( i18n("Update/revert") );
00177 actionUpdate->setWhatsThis( i18n("<b>Update/revert to another release</b><p>Updates/reverts file(s) to another release.") );
00178
00179 actionRemoveSticky = new KAction( i18n("R&emove Sticky Flag"), 0,
00180 this, SLOT(slotActionRemoveSticky()), actionCollection(), "cvsservice_removesticky" );
00181 actionRemoveSticky->setToolTip( i18n("Remove sticky flag") );
00182 actionRemoveSticky->setWhatsThis( i18n("<b>Remove sticky flag</b><p>Removes sticky flag from file(s).") );
00183
00184 actionTag = new KAction( i18n("Make &Tag/Branch"), 0,
00185 this, SLOT(slotActionTag()), actionCollection(), "cvsservice_tag" );
00186 actionTag->setToolTip( i18n("Make tag/branch") );
00187 actionTag->setWhatsThis( i18n("<b>Make tag/branch</b><p>Tags/branches selected file(s).") );
00188
00189 actionUnTag = new KAction( i18n("&Delete Tag/Branch"), 0,
00190 this, SLOT(slotActionUnTag()), actionCollection(), "cvsservice_untag" );
00191 actionUnTag->setToolTip( i18n("Delete tag/branch") );
00192 actionUnTag->setWhatsThis( i18n("<b>Delete tag/branch</b><p>Delete tag/branches from selected file(s).") );
00193
00194 actionAddToIgnoreList = new KAction( i18n("&Ignore in CVS Operations"), 0,
00195 this, SLOT(slotActionAddToIgnoreList()), actionCollection(), "cvsservice_ignore" );
00196 actionAddToIgnoreList->setToolTip( i18n("Ignore in CVS operations") );
00197 actionAddToIgnoreList->setWhatsThis( i18n("<b>Ignore in CVS operations</b><p>Ignore file(s) by adding it to .cvsignore file.") );
00198
00199 actionRemoveFromIgnoreList = new KAction( i18n("Do &Not Ignore in CVS Operations"), 0,
00200 this, SLOT(slotActionRemoveFromIgnoreList()), actionCollection(), "cvsservice_donot_ignore" );
00201 actionRemoveFromIgnoreList->setToolTip( i18n("Do not ignore in CVS operations") );
00202 actionRemoveFromIgnoreList->setWhatsThis( i18n("<b>Do not ignore in CVS operations</b><p>Do not ignore file(s) by removing\nit from .cvsignore file.") );
00203
00204 actionLogin = new KAction( i18n("&Log to Server"), 0, this,
00205 SLOT(slotActionLogin()), actionCollection(), "cvsservice_login" );
00206 actionLogin->setToolTip( i18n("Login to server") );
00207 actionLogin->setWhatsThis( i18n("<b>Login to server</b><p>Logs in to the CVS server.") );
00208
00209 actionLogout = new KAction( i18n("L&ogout From Server"), 0, this,
00210 SLOT(slotActionLogout()), actionCollection(), "cvsservice_logout" );
00211 actionLogout->setToolTip( i18n("Logout from server") );
00212 actionLogout->setWhatsThis( i18n("<b>Logout from server</b><p>Logs out from the CVS server.") );
00213 }
00214
00216
00217 bool CvsServicePart::fetchFromRepository()
00218 {
00219 return m_impl->checkout();
00220 }
00221
00223
00224 KDevVCSFileInfoProvider *CvsServicePart::fileInfoProvider() const
00225 {
00226 return m_impl->fileInfoProvider();
00227 }
00228
00230
00231 void CvsServicePart::createNewProject( const QString &dirName )
00232 {
00233 kdDebug( 9006 ) << "====> CvsServicePart::createNewProject( const QString& )" << endl;
00234
00235 if (!m_cvsConfigurationForm)
00236 return;
00237
00239
00240
00241
00242
00243 g_projectWasJustCreated = true;
00244
00245 m_impl->createNewProject( dirName,
00246 m_cvsConfigurationForm->cvsRsh(), m_cvsConfigurationForm->location(),
00247 m_cvsConfigurationForm->message(), m_cvsConfigurationForm->module(),
00248 m_cvsConfigurationForm->vendor(), m_cvsConfigurationForm->release(),
00249 m_cvsConfigurationForm->mustInitRoot()
00250 );
00251 }
00252
00254
00255 void CvsServicePart::projectConfigWidget( KDialogBase *dlg )
00256 {
00257 QVBox *vbox = dlg->addVBoxPage( i18n("CvsService"), i18n("CvsService"), BarIcon( icon(), KIcon::SizeMedium) );
00258 CvsOptionsWidget *w = new CvsOptionsWidget( (QWidget *)vbox, "cvs config widget" );
00259 connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) );
00260 }
00261
00263
00264 QWidget* CvsServicePart::newProjectWidget( QWidget *parent )
00265 {
00266 m_cvsConfigurationForm = new CvsForm( parent, "cvsform" );
00267 return m_cvsConfigurationForm;
00268 }
00269
00271
00272 void CvsServicePart::contextMenu( QPopupMenu *popup, const Context *context )
00273 {
00274
00275
00276 if(!project() || !isValidDirectory(project()->projectDirectory()))
00277 return;
00278
00279 kdDebug(9006) << "contextMenu()" << endl;
00280 if (context->hasType( Context::FileContext ) ||
00281 context->hasType( Context::EditorContext ))
00282 {
00283
00284 if (context->hasType( Context::FileContext ))
00285 {
00286 kdDebug(9006) << "Requested for a FileContext" << endl;
00287 const FileContext *fcontext = static_cast<const FileContext*>( context );
00288 m_urls = fcontext->urls();
00289 }
00290 else
00291 {
00292 kdDebug(9006) << "Requested for an EditorContext" << endl;
00293 const EditorContext *editorContext = static_cast<const EditorContext*>( context );
00294
00295 m_urls = editorContext->url();
00296 }
00297
00298 URLUtil::dump( m_urls );
00299 if (m_urls.count() <= 0)
00300 return;
00301
00302 KPopupMenu *subMenu = new KPopupMenu( popup );
00303 if (context->hasType( Context::FileContext ))
00304 popup->insertSeparator();
00305
00306 int id = subMenu->insertItem( actionCommit->text(), this, SLOT(slotCommit()) );
00307 subMenu->setWhatsThis(id, i18n("<b>Commit file(s)</b><p>Commits file to repository if modified."));
00308
00309 if (m_urls.count() == 1)
00310 {
00311 id = subMenu->insertItem( actionDiff->text(), this, SLOT(slotDiff()) );
00312 subMenu->setWhatsThis(id, i18n("<b>Build difference</b><p>Builds difference between releases."));
00313 id = subMenu->insertItem( actionLog->text(), this, SLOT(slotLog()) );
00314 subMenu->setWhatsThis(id, i18n("<b>Generate log</b><p>Produces log for this file."));
00315 }
00316 id = subMenu->insertItem( actionAdd->text(), this, SLOT(slotAdd()) );
00317 subMenu->setWhatsThis(id, i18n("<b>Add to repository</b><p>Adds file to repository."));
00318 id = subMenu->insertItem( actionAddBinary->text(), this, SLOT(slotAddBinary()) );
00319 subMenu->setWhatsThis(id, i18n("<b>Add to repository as binary</b><p>Adds file to repository as binary (-kb option)."));
00320 id = subMenu->insertItem( actionRemove->text(), this, SLOT(slotRemove()) );
00321 subMenu->setWhatsThis(id, i18n("<b>Remove from repository</b><p>Removes file(s) from repository."));
00322
00323 subMenu->insertSeparator();
00324 id = subMenu->insertItem( actionTag->text(), this, SLOT(slotTag()) );
00325 subMenu->setWhatsThis(id, i18n("<b>Make tag/branch</b><p>Tags/branches selected file(s)."));
00326 id = subMenu->insertItem( actionUnTag->text(), this, SLOT(slotUnTag()) );
00327 subMenu->setWhatsThis(id, i18n("<b>Delete tag/branch</b><p>Delete tag/branches from selected file(s)."));
00328 id = subMenu->insertItem( actionUpdate->text(), this, SLOT(slotUpdate()) );
00329 subMenu->setWhatsThis(id, i18n("<b>Update/revert to another release</b><p>Updates/reverts file(s) to another release."));
00330 id = subMenu->insertItem( actionRemoveSticky->text(), this, SLOT(slotRemoveSticky()) );
00331 subMenu->setWhatsThis(id, i18n("<b>Remove sticky flag</b><p>Removes sticky flag from file(s)."));
00332
00333 subMenu->insertSeparator();
00334 id = subMenu->insertItem( actionAddToIgnoreList->text(), this, SLOT(slotAddToIgnoreList()) );
00335 subMenu->setWhatsThis(id, i18n("<b>Ignore in CVS operations</b><p>Ignore file(s) by adding it to .cvsignore file."));
00336 id = subMenu->insertItem( actionRemoveFromIgnoreList->text(), this, SLOT(slotRemoveFromIgnoreList()) );
00337 subMenu->setWhatsThis(id, i18n("<b>Do not ignore in CVS operations</b><p>Do not ignore file(s) by removing\nit from .cvsignore file."));
00338
00339
00340 popup->insertItem( i18n("CvsService"), subMenu );
00341 }
00342 }
00343
00345
00346 bool CvsServicePart::urlFocusedDocument( KURL &url )
00347 {
00348 kdDebug(9006) << "CvsServicePartImpl::retrieveUrlFocusedDocument() here!" << endl;
00349 KParts::ReadOnlyPart *part = dynamic_cast<KParts::ReadOnlyPart*>( partController()->activePart() );
00350 if ( part )
00351 {
00352 if (part->url().isLocalFile() )
00353 {
00354 url = part->url();
00355 return true;
00356 }
00357 else
00358 {
00359 kdDebug(9006) << "Cannot handle non-local files!" << endl;
00360 }
00361 }
00362 return false;
00363 }
00364
00366
00367 bool CvsServicePart::isValidDirectory( const QString &dirPath ) const
00368 {
00369 return m_impl->isValidDirectory( dirPath );
00370 }
00371
00373
00374 void CvsServicePart::slotActionLogin()
00375 {
00376 m_impl->login();
00377 }
00378
00380
00381 void CvsServicePart::slotActionLogout()
00382 {
00383 m_impl->logout();
00384 }
00385
00387
00388 void CvsServicePart::slotActionCommit()
00389 {
00390 KURL currDocument;
00391 if (urlFocusedDocument( currDocument ))
00392 {
00393 m_impl->commit( currDocument );
00394 }
00395 }
00396
00398
00399 void CvsServicePart::slotActionUpdate()
00400 {
00401 KURL currDocument;
00402 if (urlFocusedDocument( currDocument ))
00403 {
00404 m_impl->update( currDocument );
00405 }
00406 }
00407
00409
00410 void CvsServicePart::slotActionAdd()
00411 {
00412 KURL currDocument;
00413 if (urlFocusedDocument( currDocument ))
00414 {
00415 m_impl->add( currDocument, false );
00416 }
00417 }
00418
00420
00421 void CvsServicePart::slotActionAddBinary()
00422 {
00423 KURL currDocument;
00424 if (urlFocusedDocument( currDocument ))
00425 {
00426 m_impl->add( currDocument, true );
00427 }
00428 }
00429
00431
00432 void CvsServicePart::slotActionRemove()
00433 {
00434 KURL currDocument;
00435 if (urlFocusedDocument( currDocument ))
00436 {
00437 m_impl->remove( currDocument );
00438 }
00439 }
00440
00442
00443 void CvsServicePart::slotActionRemoveSticky()
00444 {
00445 KURL currDocument;
00446 if (urlFocusedDocument( currDocument ))
00447 {
00448 m_impl->removeStickyFlag( currDocument );
00449 }
00450 }
00451
00453
00454 void CvsServicePart::slotActionLog()
00455 {
00456 KURL currDocument;
00457 if (urlFocusedDocument( currDocument ))
00458 {
00459 m_impl->log( currDocument );
00460 }
00461 }
00462
00464
00465 void CvsServicePart::slotActionDiff()
00466 {
00467 KURL currDocument;
00468 if (urlFocusedDocument( currDocument ))
00469 {
00470 m_impl->diff( currDocument );
00471 }
00472 }
00473
00475
00476 void CvsServicePart::slotActionTag()
00477 {
00478 KURL currDocument;
00479 if (urlFocusedDocument( currDocument ))
00480 {
00481 m_impl->tag( currDocument );
00482 }
00483 }
00484
00486
00487 void CvsServicePart::slotActionUnTag()
00488 {
00489 KURL currDocument;
00490 if (urlFocusedDocument( currDocument ))
00491 {
00492 m_impl->unTag( currDocument );
00493 }
00494 }
00495
00497
00498 void CvsServicePart::slotActionAddToIgnoreList()
00499 {
00500 KURL currDocument;
00501 if (urlFocusedDocument( currDocument ))
00502 {
00503 m_impl->addToIgnoreList( currDocument );
00504 }
00505 }
00506
00508
00509 void CvsServicePart::slotActionRemoveFromIgnoreList()
00510 {
00511 KURL currDocument;
00512 if (urlFocusedDocument( currDocument ))
00513 {
00514 m_impl->removeFromIgnoreList( currDocument );
00515 }
00516 }
00517
00519
00520 void CvsServicePart::slotCommit()
00521 {
00522 m_impl->commit( m_urls );
00523 }
00524
00526
00527 void CvsServicePart::slotUpdate()
00528 {
00529 m_impl->update( m_urls );
00530 }
00531
00533
00534 void CvsServicePart::slotAdd()
00535 {
00536 m_impl->add( m_urls, false );
00537 }
00538
00540
00541 void CvsServicePart::slotAddBinary()
00542 {
00543 m_impl->add( m_urls, true );
00544 }
00545
00547
00548 void CvsServicePart::slotRemove()
00549 {
00550 m_impl->remove( m_urls );
00551 }
00552
00554
00555 void CvsServicePart::slotRemoveSticky()
00556 {
00557 m_impl->removeStickyFlag( m_urls );
00558 }
00559
00561
00562 void CvsServicePart::slotLog()
00563 {
00564 m_impl->log( m_urls );
00565 }
00566
00568
00569 void CvsServicePart::slotDiff()
00570 {
00571 m_impl->diff( m_urls );
00572 }
00573
00575
00576 void CvsServicePart::slotTag()
00577 {
00578 m_impl->tag( m_urls );
00579 }
00580
00582
00583 void CvsServicePart::slotUnTag()
00584 {
00585 m_impl->unTag( m_urls );
00586 }
00587
00589
00590 void CvsServicePart::slotAddToIgnoreList()
00591 {
00592 m_impl->addToIgnoreList( m_urls );
00593 }
00594
00596
00597 void CvsServicePart::slotRemoveFromIgnoreList()
00598 {
00599 m_impl->removeFromIgnoreList( m_urls );
00600 }
00601
00603
00604 void CvsServicePart::slotStopButtonClicked( KDevPlugin* which )
00605 {
00606 if ( which != 0 && which != this )
00607 return;
00608
00609 m_impl->flushJobs();
00610 }
00611
00613
00614 void CvsServicePart::slotAddFilesToProject( const QStringList &filesToAdd )
00615 {
00616 m_impl->addFilesToProject( filesToAdd );
00617 }
00618
00620
00621 void CvsServicePart::slotRemovedFilesFromProject(const QStringList &fileToRemove)
00622 {
00623 m_impl->removedFilesFromProject( fileToRemove );
00624 }
00625
00627
00628 void CvsServicePart::slotProjectOpened()
00629 {
00630 kdDebug(9006) << "CvsServicePart::slotProjectOpened() here!" << endl;
00631
00632
00633 if (!isValidDirectory( project()->projectDirectory() ))
00634 {
00635 kdDebug(9006) << "Project has no CVS Support: too bad!! :-(" << endl;
00636 return;
00637 }
00638
00639 CvsOptions *options = CvsOptions::instance();
00640
00641
00642 if (g_projectWasJustCreated)
00643 {
00644 options->save( project() );
00645 g_projectWasJustCreated = false;
00646 }
00647 options->load( project() );
00648
00649
00650 connect( project(), SIGNAL(addedFilesToProject(const QStringList&)), this, SLOT(slotAddFilesToProject(const QStringList &)) );
00651 connect( project(), SIGNAL(removedFilesFromProject(const QStringList&)), this, SLOT(slotRemovedFilesFromProject(const QStringList &)) );
00652 }
00653
00655
00656 void CvsServicePart::slotProjectClosed()
00657 {
00658 kdDebug(9006) << "CvsServicePart::slotProjectClosed() here!" << endl;
00659
00660
00661 if (!isValidDirectory( project()->projectDirectory() ))
00662 {
00663 kdDebug(9006) << "Project had no CVS Support: too bad!! :-(" << endl;
00664 return;
00665 }
00666
00667 CvsOptions *options = CvsOptions::instance();
00668 options->save( project() );
00669 delete options;
00670
00671
00672 disconnect( project(), SIGNAL(addedFilesToProject(const QStringList&)), this, SLOT(slotAddFilesToProject(const QStringList &)) );
00673 disconnect( project(), SIGNAL(removedFilesFromProject(const QStringList&)), this, SLOT(slotRemovedFilesFromProject(const QStringList &)) );
00674 }
00675
00676 #include "cvspart.moc"
00677