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.
1013 lines
31 KiB
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 <tdeapplication.h>
|
|
#include <tdemessagebox.h>
|
|
#include <kdebug.h>
|
|
#include <tdeversion.h>
|
|
#include <tdelocale.h>
|
|
#include <kprocess.h>
|
|
#include <kstandarddirs.h>
|
|
#include <tdemainwindow.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 (TDEApplication::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"
|