You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/vcs/cvsservice/cvspartimpl.cpp

1013 lines
31 KiB

/***************************************************************************
* Copyright (C) 2003 by Mario Scalas *
* mario.scalas@libero.it *
* *
* 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 <tqfile.h>
#include <tqfileinfo.h>
#include <tqdir.h>
#include<tqcheckbox.h>
#include <kapplication.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <tdeversion.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 TQString CvsServicePartImpl::changeLogFileName( "ChangeLog" );
// Four spaces for every log line (except the first, which includes the
// developers name)
const TQString CvsServicePartImpl::changeLogPrependString( " " );
///////////////////////////////////////////////////////////////////////////////
// class CvsServicePartImpl
///////////////////////////////////////////////////////////////////////////////
CvsServicePartImpl::CvsServicePartImpl( CvsServicePart *part, const char *name )
: TQObject( 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(), TQT_SIGNAL(projectOpened()), this, TQT_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;
}
///////////////////////////////////////////////////////////////////////////////
TQStringList CvsServicePartImpl::fileList( bool relativeToProjectDir ) const
{
if (relativeToProjectDir)
return URLUtil::toRelativePaths( projectDirectory(), urlList() );
else
return urlList().toStringList();
}
///////////////////////////////////////////////////////////////////////////////
bool CvsServicePartImpl::isRegisteredInRepository( const TQString &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 TQString &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;
}
TQValueList<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 TQString &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 TQString &projectDirectory, const KURL::List &urls )
{
for (size_t i=0; i<urls.count(); ++i)
{
addToIgnoreList( projectDirectory, urls[i] );
}
}
///////////////////////////////////////////////////////////////////////////////
void CvsServicePartImpl::removeFromIgnoreList( const TQString &/*projectDirectory*/, const KURL &url )
{
kdDebug(9006) << k_funcinfo << endl;
TQStringList ignoreLines;
CVSDir cvsdir( url.directory() );
cvsdir.doNotIgnoreFile( url.fileName() );
}
void CvsServicePartImpl::removeFromIgnoreList( const TQString &projectDirectory, const KURL::List &urls )
{
for (size_t i=0; i<urls.count(); ++i)
{
removeFromIgnoreList( projectDirectory, urls[i] );
}
}
///////////////////////////////////////////////////////////////////////////////
bool CvsServicePartImpl::isValidDirectory( const TQDir &dir ) const
{
CVSDir cvsdir( dir );
return cvsdir.isValid();
}
///////////////////////////////////////////////////////////////////////////////
CvsProcessWidget *CvsServicePartImpl::processWidget() const
{
return m_widget;
}
///////////////////////////////////////////////////////////////////////////////
KDevMainWindow *CvsServicePartImpl::mainWindow() const
{
return m_part->mainWindow();
}
///////////////////////////////////////////////////////////////////////////////
TQString CvsServicePartImpl::projectDirectory() const
{
return m_part->project() ? m_part->project()->projectDirectory() : TQString();
}
///////////////////////////////////////////////////////////////////////////////
KDevCore *CvsServicePartImpl::core() const
{
return m_part->core();
}
///////////////////////////////////////////////////////////////////////////////
KDevDiffFrontend *CvsServicePartImpl::diffFrontend() const
{
return m_part->extension<KDevDiffFrontend>("TDevelop/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() == TQDialog::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(), TQT_SIGNAL(jobFinished(bool,int)), this, TQT_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() == TQDialog::Rejected)
return;
CvsOptions *options = CvsOptions::instance();
TQString 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(), TQT_SIGNAL(jobFinished(bool,int)), this, TQT_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() == TQDialog::Rejected)
return;
TQString 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(), TQT_SIGNAL(jobFinished(bool,int)), this, TQT_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(), TQT_SIGNAL(jobFinished(bool,int)), this, TQT_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
TQString 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
TQFile fileTag(tagFilename);
TQString 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 ) ) {
TQTextStream stream( &fileTag );
TQString 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(), TQT_SIGNAL(jobFinished(bool,int)), this, TQT_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(), TQT_SIGNAL(jobFinished(bool,int)), this, TQT_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(), TQT_SIGNAL(jobFinished(bool,int)),
this, TQT_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(), TQT_SIGNAL(jobFinished(bool,int)),
this, TQT_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() != TQDialog::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(), TQT_SIGNAL(jobFinished(bool,int)),
this, TQT_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() != TQDialog::Accepted)
return;
DCOPRef cvsJob = m_cvsService->createTag( fileList(), dlg.tagName(),
dlg.isBranch(), dlg.force() );
m_scheduler->schedule( cvsJob );
connect( processWidget(), TQT_SIGNAL(jobFinished(bool,int)),
this, TQT_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() != TQDialog::Accepted)
return;
DCOPRef cvsJob = m_cvsService->deleteTag( fileList(), dlg.tagName(),
dlg.isBranch(), dlg.force() );
m_scheduler->schedule( cvsJob );
connect( processWidget(), TQT_SIGNAL(jobFinished(bool,int)),
this, TQT_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 TQString &dirName,
const TQString &cvsRsh, const TQString &location,
const TQString &message, const TQString &module, const TQString &vendor,
const TQString &release, bool mustInitRoot )
{
kdDebug( 9006 ) << "====> CvsServicePartImpl::createNewProject( const TQString& )" << endl;
CvsOptions *options = CvsOptions::instance();
options->setCvsRshEnvVar( cvsRsh );
options->setLocation( location );
/*
//virtual DCOPRef import( const TQString& workingDir, const TQString& repository, const TQString& module, const TQString& ignoreList, const TQString& comment, const
TQString filesToIgnore;
DCOPRef cvsJob = m_cvsService->import( dirName, location, module, filesToIgnore, message, vendor, release, false );
m_scheduler->schedule( cvsJob );
connect( processWidget(), TQT_SIGNAL(jobFinished(bool,int)), this, TQT_SLOT(slotCheckoutFinished(bool,int)) );
*/
TQString rsh_preamble;
if ( !options->cvsRshEnvVar().isEmpty() )
rsh_preamble = "CVS_RSH=" + KShellProcess::quote( options->cvsRshEnvVar() );
TQString init;
if (mustInitRoot)
{
init = rsh_preamble + " cvs -d " + KShellProcess::quote( options->location() ) + " init && ";
}
TQString 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>("TDevelop/MakeFrontend"))
makeFrontend->queueCommand( dirName, cmdLine );
}
///////////////////////////////////////////////////////////////////////////////
bool CvsServicePartImpl::requestCvsService()
{
TQCString appId;
TQString error;
if (KApplication::startServiceByDesktopName( "cvsservice",
TQStringList(), &error, &appId ))
{
TQString 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 TQStringList &filesToAdd )
{
kdDebug( 9006 ) << k_funcinfo << " " << filesToAdd << endl;
TQStringList 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 TQStringList &filesToRemove)
{
kdDebug( 9006 ) << k_funcinfo << endl;
TQStringList 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 );
}
}
///////////////////////////////////////////////////////////////////////////////
TQStringList CvsServicePartImpl::checkFileListAgainstCVS( const TQStringList &filesToCheck ) const
{
TQStringList filesInCVS;
for (TQStringList::const_iterator it = filesToCheck.begin(); it != filesToCheck.end(); ++it )
{
const TQString &fn = (*it);
TQFileInfo fi( fn );
if (fi.isRelative())
fi = projectDirectory() + TQDir::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 );
TQString 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?"),
TQStringList::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 = TQString();
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"