diff options
Diffstat (limited to 'vcs/cvsservice/cvspartimpl.cpp')
-rw-r--r-- | vcs/cvsservice/cvspartimpl.cpp | 1012 |
1 files changed, 1012 insertions, 0 deletions
diff --git a/vcs/cvsservice/cvspartimpl.cpp b/vcs/cvsservice/cvspartimpl.cpp new file mode 100644 index 00000000..e6177739 --- /dev/null +++ b/vcs/cvsservice/cvspartimpl.cpp @@ -0,0 +1,1012 @@ +/*************************************************************************** + * Copyright (C) 2003 by Mario Scalas * + * [email protected] * + * * + * 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 <qfile.h> +#include <qfileinfo.h> +#include <qdir.h> +#include<qcheckbox.h> + +#include <kapplication.h> +#include <kmessagebox.h> +#include <kdebug.h> +#include <kdeversion.h> +#include <klocale.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <kmainwindow.h> +#include <dcopref.h> +// CvsService stuff +#include <repository_stub.h> +#include <cvsservice_stub.h> +#include <cvsjob_stub.h> +// KDevelop SDK stuff +#include <urlutil.h> +#include <kdevproject.h> +#include <kdevmainwindow.h> +#include <kdevcore.h> +#include <kdevdifffrontend.h> +#include <kdevmakefrontend.h> +#include <kdevpartcontroller.h> +// Part's widgets +#include "cvsprocesswidget.h" +#include "checkoutdialog.h" +#include "commitdlg.h" +#include "tagdialog.h" +#include "diffdialog.h" +#include "releaseinputdialog.h" +#include "cvslogdialog.h" +#include "editorsdialog.h" +#include "annotatedialog.h" + +#include "changelog.h" +#include "cvsoptions.h" +#include "cvsdir.h" +#include "cvsentry.h" +#include "jobscheduler.h" +#include "cvsfileinfoprovider.h" + +#include "cvspart.h" +#include "cvspartimpl.h" + +/////////////////////////////////////////////////////////////////////////////// +// class Constants +/////////////////////////////////////////////////////////////////////////////// + +// Nice name (relative to projectDirectory()) ;-) +const QString CvsServicePartImpl::changeLogFileName( "ChangeLog" ); +// Four spaces for every log line (except the first, which includes the +// developers name) +const QString CvsServicePartImpl::changeLogPrependString( " " ); + +/////////////////////////////////////////////////////////////////////////////// +// class CvsServicePartImpl +/////////////////////////////////////////////////////////////////////////////// + +CvsServicePartImpl::CvsServicePartImpl( CvsServicePart *part, const char *name ) + : QObject( this, name? name : "cvspartimpl" ), + m_scheduler( 0 ), m_part( part ), m_widget( 0 ) +{ + if (requestCvsService()) + { + m_widget = new CvsProcessWidget( m_cvsService, part, 0, "cvsprocesswidget" ); + m_scheduler = new DirectScheduler( m_widget ); + m_fileInfoProvider = new CVSFileInfoProvider( part, m_cvsService ); + + connect( core(), SIGNAL(projectOpened()), this, SLOT(slotProjectOpened()) ); + } + else + { + kdDebug(9006) << "CvsServicePartImpl::CvsServicePartImpl(): somebody kills me because" + "I could not request a valid CvsService!!!! :-((( " << endl; + } + +} + +/////////////////////////////////////////////////////////////////////////////// + +CvsServicePartImpl::~CvsServicePartImpl() +{ + if (processWidget()) + { + // Inform toplevel, that the output view is gone + mainWindow()->removeView( m_widget ); + delete m_widget; + } + delete m_scheduler; + //delete m_fileInfoProvider; + releaseCvsService(); +} + +/////////////////////////////////////////////////////////////////////////////// + +bool CvsServicePartImpl::prepareOperation( const KURL::List &someUrls, CvsOperation op ) +{ + kdDebug(9006) << k_funcinfo << endl; + + bool correctlySetup = (m_cvsService != 0) && (m_repository != 0); + if (!correctlySetup) + { + kdDebug(9006) << "DCOP CvsService is not available!!!" << endl; + return false; + } + + KURL::List urls = someUrls; + URLUtil::dump( urls, "Requested CVS operation for: " ); + + if (!m_part->project()) + { + kdDebug(9006) << k_funcinfo << "No project???" << endl; + KMessageBox::sorry( 0, i18n("Open a project first.\nOperation will be aborted.") ); + return false; + } + + if (m_widget->isAlreadyWorking()) + { + if (KMessageBox::warningYesNo( 0, + i18n("Another CVS operation is executing: do you want to cancel it \n" + "and start this new one?"), + i18n("CVS: Operation Already Pending ")) == KMessageBox::Yes) + { + m_widget->cancelJob(); + } + else // Operation canceled + { + kdDebug(9006) << k_funcinfo << "Operation canceled by user request" << endl; + return false; + } + } + + validateURLs( projectDirectory(), urls, op ); + if (urls.count() <= 0) // who knows? ;) + { + kdDebug(9006) << "CvsServicePartImpl::prepareOperation(): No valid document URL selected!!!" << endl; + KMessageBox::sorry( 0, i18n("None of the file(s) you selected seem to be valid for repository.") ); + return false; + } + + URLUtil::dump( urls ); + // Save for later use + m_urlList = urls; + m_lastOperation = op; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::doneOperation( const KURL::List &/*someUrls*/, CvsOperation /*op*/ ) +{ + kdDebug(9006) << k_funcinfo << endl; + + // @ todo notify clients (filetree) about changed status?) +} + +/////////////////////////////////////////////////////////////////////////////// + +const KURL::List &CvsServicePartImpl::urlList() const +{ + return m_urlList; +} + +/////////////////////////////////////////////////////////////////////////////// + +QStringList CvsServicePartImpl::fileList( bool relativeToProjectDir ) const +{ + if (relativeToProjectDir) + return URLUtil::toRelativePaths( projectDirectory(), urlList() ); + else + return urlList().toStringList(); +} + +/////////////////////////////////////////////////////////////////////////////// + +bool CvsServicePartImpl::isRegisteredInRepository( const QString &projectDirectory, const KURL &url ) +{ + kdDebug(9006) << k_funcinfo << endl; + + // KURL::directory() is a bit tricky when used on file or _dir_ paths ;-) + KURL projectURL = KURL::fromPathOrURL( projectDirectory ); + kdDebug(9006) << k_funcinfo << "projectURL = " << projectURL.url() << endl; + kdDebug(9006) << k_funcinfo << "url = " << url.url() << endl; + + if ( projectURL == url) + { + CVSDir cvsdir = CVSDir( projectDirectory ); + return cvsdir.isValid(); + } + else + { + CVSDir cvsdir = CVSDir( url.directory() ); + + if (!cvsdir.isValid()) + { + kdDebug(9006) << k_funcinfo << " Error: " << cvsdir.path() << " is not a valid CVS directory " << endl; + return false; + } + CVSEntry entry = cvsdir.fileStatus( url.fileName() ); + return entry.isValid(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::validateURLs( const QString &projectDirectory, KURL::List &urls, CvsOperation op ) +{ + kdDebug(9006) << k_funcinfo << endl; + + // If files are to be added, we can avoid to check them to see if they are registered in the + // repository ;) + if (op == opAdd) + { + kdDebug(9006) << "This is a Cvs Add operation and will not be checked against repository ;-)" << endl; + return; + } + QValueList<KURL>::iterator it = urls.begin(); + while (it != urls.end()) + { + if (!CvsServicePartImpl::isRegisteredInRepository( projectDirectory, (*it) )) + { + kdDebug(9006) << "Warning: file " << (*it).path() << " does NOT belong to repository and will not be used" << endl; + + it = urls.erase( it ); + } + else + { + kdDebug(9006) << "Warning: file " << (*it).path() << " is in repository and will be accepted" << endl; + + ++it; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::addToIgnoreList( const QString &projectDirectory, const KURL &url ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if ( url.path() == projectDirectory ) + { + kdDebug(9006) << "Can't add to ignore list current project directory " << endl; + return; + } + + CVSDir cvsdir( url.directory() ); + cvsdir.ignoreFile( url.fileName() ); +} + +void CvsServicePartImpl::addToIgnoreList( const QString &projectDirectory, const KURL::List &urls ) +{ + for (size_t i=0; i<urls.count(); ++i) + { + addToIgnoreList( projectDirectory, urls[i] ); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::removeFromIgnoreList( const QString &/*projectDirectory*/, const KURL &url ) +{ + kdDebug(9006) << k_funcinfo << endl; + + QStringList ignoreLines; + + CVSDir cvsdir( url.directory() ); + cvsdir.doNotIgnoreFile( url.fileName() ); +} + +void CvsServicePartImpl::removeFromIgnoreList( const QString &projectDirectory, const KURL::List &urls ) +{ + for (size_t i=0; i<urls.count(); ++i) + { + removeFromIgnoreList( projectDirectory, urls[i] ); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +bool CvsServicePartImpl::isValidDirectory( const QDir &dir ) const +{ + CVSDir cvsdir( dir ); + + return cvsdir.isValid(); +} + +/////////////////////////////////////////////////////////////////////////////// + +CvsProcessWidget *CvsServicePartImpl::processWidget() const +{ + return m_widget; +} + +/////////////////////////////////////////////////////////////////////////////// + +KDevMainWindow *CvsServicePartImpl::mainWindow() const +{ + return m_part->mainWindow(); +} + +/////////////////////////////////////////////////////////////////////////////// + +QString CvsServicePartImpl::projectDirectory() const +{ + return m_part->project() ? m_part->project()->projectDirectory() : QString::null; +} + +/////////////////////////////////////////////////////////////////////////////// + +KDevCore *CvsServicePartImpl::core() const +{ + return m_part->core(); +} + +/////////////////////////////////////////////////////////////////////////////// + +KDevDiffFrontend *CvsServicePartImpl::diffFrontend() const +{ + return m_part->extension<KDevDiffFrontend>("KDevelop/DiffFrontend"); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::login() +{ + DCOPRef job = m_cvsService->login( this->projectDirectory() ); + + m_scheduler->schedule( job ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::logout() +{ + DCOPRef job = m_cvsService->logout( this->projectDirectory() ); + + m_scheduler->schedule( job ); +} + +/////////////////////////////////////////////////////////////////////////////// + +bool CvsServicePartImpl::checkout() +{ + kdDebug(9006) << k_funcinfo << endl; + + CheckoutDialog dlg( m_cvsService, mainWindow()->main()->centralWidget() ); + + if ( dlg.exec() == QDialog::Accepted ) + { + DCOPRef job = m_cvsService->checkout( dlg.workDir(), dlg.serverPath(), + dlg.module(), dlg.tag(), dlg.pruneDirs(), "", false + ); + if (!m_cvsService->ok()) { + KMessageBox::sorry( mainWindow()->main(), i18n( "Unable to checkout" ) ); + } else { + // Save the path for later retrieval since slotCheckoutFinished(bool,int) + // will use it for return the info to the caller. + modulePath = dlg.workDir() + dlg.module(); + + m_scheduler->schedule( job ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), this, SLOT(slotCheckoutFinished(bool,int)) ); + return true; + } + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::commit( const KURL::List& urlList ) +{ + kdDebug(9006) << k_funcinfo << endl; + kdDebug(9006) << "Commit requested for " << urlList.count() << " file(s)." << endl; + + if (!prepareOperation( urlList, opCommit )) + return; + + CommitDialog dlg( projectDirectory() + "/ChangeLog" ); + if (dlg.exec() == QDialog::Rejected) + return; + + CvsOptions *options = CvsOptions::instance(); + QString logString = dlg.logMessage().join( "\n" ); + + DCOPRef cvsJob = m_cvsService->commit( fileList(), logString, options->recursiveWhenCommitRemove() ); + if (!m_cvsService->ok()) + { + kdDebug( 9006 ) << "Commit of " << fileList().join( ", " ) << " failed!!!" << endl; + return; + } + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), this, SLOT(slotJobFinished(bool,int)) ); + + // 2. if requested to do so, add an entry to the Changelog too + if (dlg.mustAddToChangeLog()) + { + // 2.1 Modify the Changelog + ChangeLogEntry entry; + entry.addLines( dlg.logMessage() ); + entry.addToLog( dlg.changeLogFileName() ); + + kdDebug( 9006 ) << " *** ChangeLog entry : " << + entry.toString( changeLogPrependString ) << endl; + } + + doneOperation( KURL::List( fileList() ), opCommit ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::update( const KURL::List& urlList ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opCommit )) + return; + + CvsOptions *options = CvsOptions::instance(); + ReleaseInputDialog dlg( mainWindow()->main()->centralWidget() ); + if (dlg.exec() == QDialog::Rejected) + return; + + QString additionalOptions = dlg.release(); + if (dlg.isRevert()) + additionalOptions = additionalOptions + " " + options->revertOptions(); + + DCOPRef cvsJob = m_cvsService->update( fileList(), + options->recursiveWhenUpdate(), + options->createDirsWhenUpdate(), + options->pruneEmptyDirsWhenUpdate(), + additionalOptions ); + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), this, SLOT(slotJobFinished(bool,int)) ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::add( const KURL::List& urlList, bool binary ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opAdd )) + return; + + DCOPRef cvsJob = m_cvsService->add( fileList(), binary ); + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), this, SLOT(slotJobFinished(bool,int)) ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::annotate( const KURL::List& urlList ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opAnnotate )) + return; + + //get the directory of the file we want to annotate + QString tagFilename = URLUtil::directory(projectDirectory()+"/"+fileList()[0]); + //CVS stores tag information in the ./CVS/Tag file + tagFilename += "/CVS/Tag"; + + + //Check if such a Tag file exists, and try to read the tag/branch from it + QFile fileTag(tagFilename); + QString strRev = ""; //default revision is empty ... + if (fileTag.exists()) { //... but if there is a Tag file, we get the revision from there + if ( fileTag.open( IO_ReadOnly ) ) { + QTextStream stream( &fileTag ); + QString line; + line = stream.readLine(); + if (line.startsWith("T")) { //the line always starts with a "T"... + strRev = line.right(line.length()-1); //...and after this there is the tag name + kdDebug(9006) << "The found revision is: >>" << strRev << "<<" <<endl; + } + fileTag.close(); + } + } + + AnnotateDialog * f = new AnnotateDialog( m_cvsService ); + f->show(); + //the dialog will do all the work, just give him the file and the revision to start with + f->startFirstAnnotate( fileList()[0], strRev ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::unedit( const KURL::List& urlList) +{ + kdDebug(9006) << k_funcinfo << endl; + + int s = KMessageBox::questionYesNo( 0, + i18n("Do you really want to unedit the selected files?"), + i18n("CVS - Unedit Files"), + i18n("Unedit"), + i18n("Do Not Unedit"), + "askUneditingFiles" ); + if (s == KMessageBox::No) { + return; + } + + if (!prepareOperation( urlList, opUnEdit )) + return; + + DCOPRef cvsJob = m_cvsService->unedit( fileList() ); + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), this, SLOT(slotJobFinished(bool,int)) ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::edit( const KURL::List& urlList) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opEdit )) + return; + + DCOPRef cvsJob = m_cvsService->edit( fileList() ); + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), this, SLOT(slotJobFinished(bool,int)) ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::editors( const KURL::List& urlList) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opEditors )) + return; + + EditorsDialog * f = new EditorsDialog( m_cvsService ); + f->show(); + //the dialog will do all the work + f->startjob( fileList()[0] ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::remove( const KURL::List& urlList ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opRemove )) + return; + + DCOPRef cvsJob = m_cvsService->remove( fileList(), true ); + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), + this, SLOT(slotJobFinished(bool,int)) ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::removeStickyFlag( const KURL::List& urlList ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opUpdate )) + return; + + CvsOptions *options = CvsOptions::instance(); + + DCOPRef cvsJob = m_cvsService->update( fileList(), + options->recursiveWhenUpdate(), + options->createDirsWhenUpdate(), + options->pruneEmptyDirsWhenUpdate(), + "-A" ); + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), + this, SLOT(slotJobFinished(bool,int)) ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::log( const KURL::List& urlList ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opLog )) + return; + + CVSLogDialog* f = new CVSLogDialog( m_cvsService ); + f->show(); + // Form will do all the work + f->startLog( projectDirectory(), fileList()[0] ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::diff( const KURL::List& urlList ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opDiff )) + return; + + CVSDir cvsdir = CVSDir( urlList[0].directory() ); + CVSEntry entry = cvsdir.fileStatus( urlList[0].fileName() ); + + DiffDialog dlg(entry); + if (dlg.exec() != QDialog::Accepted) + return; + + CvsOptions *options = CvsOptions::instance(); + DCOPRef cvsJob = m_cvsService->diff( fileList()[0], dlg.revA(), + dlg.revB(), options->diffOptions(), options->contextLines() ); + if (!m_cvsService->ok()) + { + KMessageBox::sorry( 0, i18n("Sorry, cannot diff."), + i18n("Error During Diff") ); + return; + } + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), + this, SLOT(slotDiffFinished(bool,int)) ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::tag( const KURL::List& urlList ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opTag )) + return; + + TagDialog dlg( i18n("Creating Tag/Branch for files ..."), + mainWindow()->main()->centralWidget() ); + if (dlg.exec() != QDialog::Accepted) + return; + + DCOPRef cvsJob = m_cvsService->createTag( fileList(), dlg.tagName(), + dlg.isBranch(), dlg.force() ); + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), + this, SLOT(slotJobFinished(bool,int)) ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::unTag( const KURL::List& urlList ) +{ + kdDebug(9006) << k_funcinfo << endl; + + if (!prepareOperation( urlList, opUnTag )) + return; + + TagDialog dlg( i18n("Removing Tag from files ..."), + mainWindow()->main()->centralWidget() ); + dlg.tagAsBranchCheck->hide(); + if (dlg.exec() != QDialog::Accepted) + return; + + DCOPRef cvsJob = m_cvsService->deleteTag( fileList(), dlg.tagName(), + dlg.isBranch(), dlg.force() ); + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), + this, SLOT(slotJobFinished(bool,int)) ); + + doneOperation(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::addToIgnoreList( const KURL::List& urlList ) +{ + addToIgnoreList( projectDirectory(), urlList ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::removeFromIgnoreList( const KURL::List& urlList ) +{ + removeFromIgnoreList( projectDirectory(), urlList ); +} + +/////////////////////////////////////////////////////////////////////////////// + +/** +* \FIXME Current implementation doesn't use CvsService :-( I just ported the +* old code which relies on buildcvs.sh script. [marios] +*/ +void CvsServicePartImpl::createNewProject( const QString &dirName, + const QString &cvsRsh, const QString &location, + const QString &message, const QString &module, const QString &vendor, + const QString &release, bool mustInitRoot ) +{ + kdDebug( 9006 ) << "====> CvsServicePartImpl::createNewProject( const QString& )" << endl; + + CvsOptions *options = CvsOptions::instance(); + options->setCvsRshEnvVar( cvsRsh ); + options->setLocation( location ); +/* + //virtual DCOPRef import( const QString& workingDir, const QString& repository, const QString& module, const QString& ignoreList, const QString& comment, const + QString filesToIgnore; + DCOPRef cvsJob = m_cvsService->import( dirName, location, module, filesToIgnore, message, vendor, release, false ); + + m_scheduler->schedule( cvsJob ); + connect( processWidget(), SIGNAL(jobFinished(bool,int)), this, SLOT(slotCheckoutFinished(bool,int)) ); +*/ + QString rsh_preamble; + if ( !options->cvsRshEnvVar().isEmpty() ) + rsh_preamble = "CVS_RSH=" + KShellProcess::quote( options->cvsRshEnvVar() ); + + QString init; + if (mustInitRoot) + { + init = rsh_preamble + " cvs -d " + KShellProcess::quote( options->location() ) + " init && "; + } + QString cmdLine = init + "cd " + KShellProcess::quote(dirName) + + " && " + rsh_preamble + + " cvs -d " + KShellProcess::quote(options->location()) + + " import -m " + KShellProcess::quote(message) + " " + + KShellProcess::quote(module) + " " + + KShellProcess::quote(vendor) + " " + + KShellProcess::quote(release) + + // CVS build-up magic here ... + " && sh " + + locate("data","kdevcvsservice/buildcvs.sh") + " . " + + KShellProcess::quote(module) + " " + + KShellProcess::quote(location); + + kdDebug( 9006 ) << " ** Will run the following command: " << endl << cmdLine << endl; + kdDebug( 9006 ) << " ** on directory: " << dirName << endl; + + if (KDevMakeFrontend *makeFrontend = m_part->extension<KDevMakeFrontend>("KDevelop/MakeFrontend")) + makeFrontend->queueCommand( dirName, cmdLine ); +} + +/////////////////////////////////////////////////////////////////////////////// + +bool CvsServicePartImpl::requestCvsService() +{ + QCString appId; + QString error; + + if (KApplication::startServiceByDesktopName( "cvsservice", + QStringList(), &error, &appId )) + { + QString msg = i18n( "Unable to find the Cervisia KPart. \n" + "Cervisia Integration will not be available. Please check your\n" + "Cervisia installation and re-try. Reason was:\n" ) + error; + KMessageBox::error( processWidget(), msg, "DCOP Error" ); + + return false; + } + else + { + m_cvsService = new CvsService_stub( appId, "CvsService" ); + m_repository = new Repository_stub( appId, "CvsRepository" ); + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::releaseCvsService() +{ + if (m_cvsService) + m_cvsService->quit(); + delete m_cvsService; + m_cvsService = 0; + delete m_repository; + m_repository = 0; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::flushJobs() +{ + processWidget()->cancelJob(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::addFilesToProject( const QStringList &filesToAdd ) +{ + kdDebug( 9006 ) << k_funcinfo << " " << filesToAdd << endl; + + QStringList filesInCVS = checkFileListAgainstCVS( filesToAdd ); + if (filesInCVS.isEmpty()) + return; + + kdDebug( 9006 ) << k_funcinfo << " " << filesInCVS << endl; + + int s = KMessageBox::questionYesNo( 0, + i18n("Do you want the files to be added to CVS repository too?"), + i18n("CVS - New Files Added to Project"), + KStdGuiItem::add(), + i18n("Do Not Add"), + i18n("askWhenAddingNewFiles") ); + if (s == KMessageBox::Yes) + { + kdDebug( 9006 ) << "Adding these files: " << filesInCVS.join( ", " ) << endl; + + const KURL::List urls = KURL::List( filesInCVS ); + URLUtil::dump( urls ); + add( urls ); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::removedFilesFromProject(const QStringList &filesToRemove) +{ + kdDebug( 9006 ) << k_funcinfo << endl; + + QStringList filesInCVS = checkFileListAgainstCVS( filesToRemove ); + if (filesInCVS.isEmpty()) + return; + + int s = KMessageBox::warningContinueCancel( 0, + i18n("Do you want them to be removed from CVS repository too?\nWarning: They will be removed from disk too."), + i18n("CVS - Files Removed From Project"), + KStdGuiItem::del(), + i18n("askWhenRemovingFiles") ); + + if (s == KMessageBox::Continue) + { + kdDebug( 9006 ) << "Removing these files: " << filesInCVS.join( ", " ) << endl; + const KURL::List urls = KURL::List( filesInCVS ); + URLUtil::dump( urls ); + remove( urls ); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +QStringList CvsServicePartImpl::checkFileListAgainstCVS( const QStringList &filesToCheck ) const +{ + QStringList filesInCVS; + for (QStringList::const_iterator it = filesToCheck.begin(); it != filesToCheck.end(); ++it ) + { + const QString &fn = (*it); + QFileInfo fi( fn ); + if (fi.isRelative()) + fi = projectDirectory() + QDir::separator() + fn; + if (isValidDirectory( fi.dirPath( true ) )) + filesInCVS += ( fi.filePath() ); + } + + return filesInCVS; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::emitFileStateModified( const KURL::List &/*urls*/, VCSFileInfo::FileState &/*commonState*/ ) +{ +} + +/////////////////////////////////////////////////////////////////////////////// + +KDevVCSFileInfoProvider *CvsServicePartImpl::fileInfoProvider() const +{ + return m_fileInfoProvider; +} + +/////////////////////////////////////////////////////////////////////////////// +// SLOTS here! +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::slotDiffFinished( bool normalExit, int exitStatus ) +{ + core()->running( m_part, false ); + + QString diff = processWidget()->output().join("\n"), + err = processWidget()->errors().join("\n"); + + kdDebug( 9006 ) << "diff = " << diff << endl; + kdDebug( 9006 ) << "err = " << err << endl; + + if (normalExit) + kdDebug( 9006 ) << " *** Process died nicely with exit status = " << + exitStatus << endl; + else + kdDebug( 9999 ) << " *** Process was killed with exit status = " << + exitStatus << endl; + + // Now show a message about operation ending status + if (diff.isEmpty() && (exitStatus != 0)) + { + KMessageBox::information( 0, i18n("Operation aborted (process killed)."), + i18n("CVS Diff") ); + return; + } + if ( diff.isEmpty() && !err.isEmpty() ) + { + KMessageBox::detailedError( 0, i18n("CVS outputted errors during diff."), + err, i18n("Errors During Diff") ); + return; + } + + if ( !err.isEmpty() ) + { + int s = KMessageBox::warningContinueCancelList( 0, + i18n("CVS output errors during diff. Do you still want to continue?"), + QStringList::split( "\n", err, false ), i18n("Errors During Diff") + ); + if ( s != KMessageBox::Continue ) + return; + } + + if ( diff.isEmpty() ) + { + KMessageBox::information( 0, i18n("There is no difference to the repository."), + i18n("No Difference Found") ); + return; + } + + Q_ASSERT( diffFrontend() ); + diffFrontend()->showDiff( diff ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::slotCheckoutFinished( bool exitStatus, int ) +{ + kdDebug(9006) << "CvsServicePartImpl::slotCheckoutFinished(): job ended with status == " + << exitStatus << endl; + // Return a null string if the operation was not succesfull + if (!exitStatus) + modulePath = QString::null; + + kdDebug(9006) << " I'll emit modulePath == " << modulePath << endl; + + emit checkoutFinished( modulePath ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::slotJobFinished( bool /*exitStatus*/, int exitCode ) +{ + // Return a null string if the operation was not succesfull + kdDebug(9006) << "CvsServicePartImpl::slotJobFinished(): job ended with code == " + << exitCode << endl; +/* + // Operation has been successfull + if (!exitStatus) + return; + + // 1. Assemble the CVSFileInfoList + // 2. notify all clients +*/ +} + +/////////////////////////////////////////////////////////////////////////////// + +void CvsServicePartImpl::slotProjectOpened() +{ + kdDebug(9006) << "CvsServicePartImpl::slotProjectOpened(): setting work directory to " + << projectDirectory() << endl; + + if ( m_repository ) + { + m_repository->setWorkingCopy( projectDirectory() ); + } +} + + +#include "cvspartimpl.moc" |