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/subversion/subversion_core.cpp

739 lines
27 KiB

/**
Copyright (C) 2003-2005 Mickael Marchand <marchand@kde.org>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <tdeparts/part.h>
#include <kdevcore.h>
#include <kdevproject.h>
#include "subversion_part.h"
#include "subversion_core.h"
#include "subversion_widget.h"
#include "svn_blamewidget.h"
#include "svn_logviewwidget.h"
#include "subversiondiff.h"
#include <kdevmainwindow.h>
#include "svn_co.h"
#include <kurlrequester.h>
#include <klineedit.h>
#include <tdeio/job.h>
#include <tdeio/jobclasses.h>
#include <tdeio/netaccess.h>
#include <kdebug.h>
#include <kmainwindow.h>
#include <kapplication.h>
#include <dcopclient.h>
#include <ktempfile.h>
#include <kprocess.h>
#include <kstandarddirs.h>
#include <tqtextcodec.h>
#include <tqtextstream.h>
#include <tqtextbrowser.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <tqregexp.h>
#include <kapplication.h>
#include <kinstance.h>
#include <kaboutdata.h>
using namespace TDEIO;
using namespace SvnGlobal;
subversionCore::subversionCore(subversionPart *part)
// : TQObject(NULL, "subversion core"), DCOPObject("subversion") {
: TQObject(NULL, "subversion core") {
m_part = part;
m_widget = new subversionWidget(part, 0 , "subversionprocesswidget");
// m_logViewWidget = new SvnLogViewWidget( part, 0 );
// m_part->mainWindow()->embedOutputView( m_logViewWidget, i18n( "Subversion Log" ), i18n( "Subversion Log" ) );
// if ( ! connectDCOPSignal("kded", "ksvnd", "subversionNotify(TQString,int,int,TQString,int,int,long int,TQString)", "notification(TQString,int,int,TQString,int,int,long int,TQString)", false ) )
// kdWarning() << "Failed to connect to kded dcop signal ! Notifications won't work..." << endl;
m_fileInfoProvider = new SVNFileInfoProvider( part );
diffTmpDir = new KTempDir();
diffTmpDir->setAutoDelete(true);
}
subversionCore::~subversionCore() {
if ( processWidget() ) {
m_part->mainWindow()->removeView( processWidget() );
delete processWidget();
}
// if( m_logViewWidget ){
// m_part->mainWindow()->removeView( m_logViewWidget );
// delete m_logViewWidget;
// }
delete diffTmpDir;
//FIXME delete m_fileInfoProvider here?
}
KDevVCSFileInfoProvider *subversionCore::fileInfoProvider() const {
return m_fileInfoProvider;
}
//not used anymore
// void subversionCore::notification( const TQString& path, int action, int kind, const TQString& mime_type, int content_state ,int prop_state ,long int revision, const TQString& userstring ) {
// kdDebug(9036) << "Subversion Notification : "
// << "path : " << path
// << "action: " << action
// << "kind : " << kind
// << "mime_type : " << mime_type
// << "content_state : " << content_state
// << "prop_state : " << prop_state
// << "revision : " << revision
// << "userstring : " << userstring
// << endl;
// if ( !userstring.isEmpty() ) {
// m_part->mainWindow()->raiseView(processWidget());
// processWidget()->append( userstring );
// }
// }
subversionWidget *subversionCore::processWidget() const {
// SvnLogViewWidget* subversionCore::processWidget() const {
// return processWidget();
// return m_logViewWidget;
return m_widget;
}
void subversionCore::resolve( const KURL::List& list ) {
KURL servURL = m_part->baseURL();
if ( servURL.isEmpty() ) servURL="kdevsvn+svn://blah/";
if ( ! servURL.protocol().startsWith( "kdevsvn+" ) ) {
servURL.setProtocol( "kdevsvn+" + servURL.protocol() ); //make sure it starts with "svn"
}
kdDebug(9036) << "servURL : " << servURL.prettyURL() << endl;
for ( TQValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
kdDebug(9036) << "resolving: " << (*it).prettyURL() << endl;
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
int cmd = 11;
bool recurse = true;
s << cmd << *it << recurse;
SimpleJob * job = TDEIO::special(servURL, parms, true);
job->setWindow( m_part->mainWindow()->main() );
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
}
}
void subversionCore::update( const KURL::List& list ) {
KURL servURL = "kdevsvn+svn://blah/";
kdDebug(9036) << "Updating. servURL : " << servURL.prettyURL() << endl;
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
int cmd = 2;
int rev = -1;
s << cmd << list << rev << TQString( "HEAD" );
SimpleJob * job = TDEIO::special(servURL, parms, false);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
initProcessDlg( (TDEIO::Job*)job, i18n("Subversion Update") , i18n("Subversion Update") );
}
void subversionCore::diff( const KURL::List& list, const TQString& where){
kdDebug(9036) << "diff " << list << endl;
KURL servURL = "kdevsvn+svn://this_is_a_fake_URL_and_this_is_normal/";
for ( TQValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
int cmd = 13;
kdDebug(9036) << "diffing : " << (*it).prettyURL() << endl;
int rev1=-1;
int rev2=-1;
TQString revkind1 = where;
TQString revkind2 = "WORKING";
s << cmd << *it << *it << rev1 << revkind1 << rev2 << revkind2 << true ;
TDEIO::SimpleJob * job = TDEIO::special(servURL, parms, true);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
TDEIO::NetAccess::synchronousRun( job, 0 );
if ( diffresult.count() > 0 ) {
//check kompare is available
if ( !TDEStandardDirs::findExe( "kompare" ).isNull() ) {
if (!TDEStandardDirs::findExe("patch").isNull()){
// we have patch - so can merge
KTempDir tmpDir = KTempDir(diffTmpDir->name());
KTempFile tmpPatch = KTempFile(tmpDir.name());
// write the patch
TQTextStream *stream = tmpPatch.textStream();
stream->setCodec( TQTextCodec::codecForName( "utf8" ) );
for ( TQStringList::Iterator it2 = diffresult.begin();it2 != diffresult.end() ; ++it2 ) {
( *stream ) << ( *it2 ) << "\n";
}
tmpPatch.close();
TQString ourCopy = tmpDir.name()+(*it).fileName();
TDEProcess copy;
copy << "cp" << (*it).prettyURL(0,KURL::StripFileProtocol) << tmpDir.name();
copy.start(TDEProcess::Block);
TDEProcess patch;
patch.setWorkingDirectory(tmpDir.name());
patch << "patch" << "-R" << ourCopy << tmpPatch.name();
patch.start(TDEProcess::Block, TDEProcess::All);
TDEProcess *p = new TDEProcess;
*p << "kompare" << ourCopy << (*it).prettyURL();
p->start();
}
else{
// only diff
KTempFile *tmp = new KTempFile;
tmp->setAutoDelete(true);
TQTextStream *stream = tmp->textStream();
stream->setCodec( TQTextCodec::codecForName( "utf8" ) );
for ( TQStringList::Iterator it2 = diffresult.begin();it2 != diffresult.end() ; ++it2 ) {
( *stream ) << ( *it2 ) << "\n";
}
tmp->close();
TDEProcess *p = new TDEProcess;
*p << "kompare" << "-n" << "-o" << tmp->name();
p->start();
}
} else { //else do it with message box
Subversion_Diff df;
for ( TQStringList::Iterator it2 = diffresult.begin();it2 != diffresult.end() ; ++it2 ) {
df.text->append( *it2 );
}
TQFont f = df.font();
f.setFixedPitch( true );
df.text->setFont( f );
df.exec();
}
}
else{
TQString diffTo = i18n("the local disk checked out copy.");
if ( where=="HEAD"){
diffTo=i18n("the current svn HEAD version.");
}
KMessageBox::information( 0, i18n("No differences between the file and %1").arg(diffTo), i18n("No difference") );
}
diffresult.clear();
}
}
void subversionCore::diffAsync( const KURL &pathOrUrl1, const KURL &pathOrUrl2,
int rev1, TQString revKind1, int rev2, TQString revKind2,
bool recurse, bool pegdiff )
{
KURL servURL = "kdevsvn+svn://blah/";
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
int cmd = 13;
kdDebug(9036) << "diffing async : " << pathOrUrl1 << " and " << pathOrUrl2 << endl;
s << cmd << pathOrUrl1 << pathOrUrl2 << rev1 << revKind1 << rev2 << revKind2 << recurse;
s << pegdiff;
TDEIO::SimpleJob * job = TDEIO::special(servURL, parms, false);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotDiffResult( TDEIO::Job * ) ) );
initProcessDlg( (TDEIO::Job*)job, pathOrUrl1.prettyURL(), pathOrUrl2.prettyURL() );
}
void subversionCore::commit( const KURL::List& list, bool recurse, bool keeplocks ) {
KURL servURL = m_part->baseURL();
if ( servURL.isEmpty() ) servURL="kdevsvn+svn://blah/";
if ( ! servURL.protocol().startsWith( "kdevsvn+" ) ) {
servURL.setProtocol( "kdevsvn+" + servURL.protocol() ); //make sure it starts with "svn"
}
kdDebug(9036) << "servURL : " << servURL.prettyURL() << endl;
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
int cmd = 103;
s << cmd << recurse << keeplocks;
for ( TQValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
kdDebug(9036) << "adding to list: " << (*it).prettyURL() << endl;
s << *it;
}
SimpleJob * job = TDEIO::special(servURL, parms, false);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
if( list.count() == 1 )
initProcessDlg( (TDEIO::Job*)job, (*(list.begin())).prettyURL() , i18n("Commit to remote repository") );
else if( list.count() > 1 )
initProcessDlg( (TDEIO::Job*)job, i18n("From working copy") , i18n("Commit to remote repository") );
}
// Right now, only one item for each action.
void subversionCore::svnLog( const KURL::List& list,
int revstart, TQString revKindStart, int revend, TQString revKindEnd,
bool discorverChangedPath, bool strictNodeHistory )
{
// ensure that part has repository information. This info is used to retrieve root repository URL
if( m_part->m_prjInfoMap.count() < 1 )
clientInfo( KURL(m_part->project()->projectDirectory()), false, m_part->m_prjInfoMap );
KURL servURL = m_part->baseURL();
if ( servURL.isEmpty() ) servURL="kdevsvn+svn://blah/";
if ( ! servURL.protocol().startsWith( "kdevsvn+" ) ) {
servURL.setProtocol( "kdevsvn+" + servURL.protocol() ); //make sure it starts with "svn"
}
kdDebug(9036) << "servURL : " << servURL.prettyURL() << endl;
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
// prepare arguments
int cmd = 4;
// int revstart = -1, revend = 0;
// TQString revKindStart = "HEAD", revKindEnd = "";
// bool repositLog = true, discorverChangedPath = true, strictNodeHistory = true;
s << cmd << revstart << revKindStart << revend << revKindEnd;
s << discorverChangedPath << strictNodeHistory;
for ( TQValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
kdDebug(9036) << "svnCore: adding to list: " << (*it).prettyURL() << endl;
s << *it;
}
SimpleJob * job = TDEIO::special(servURL, parms, false);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotLogResult( TDEIO::Job * ) ) );
// progress info. LogView is allowed and meaninful only for one url in KDev3.4
initProcessDlg( (TDEIO::Job*)job, (*(list.begin())).prettyURL() , i18n("Subversion Log View") );
}
void subversionCore::blame( const KURL &url, UrlMode mode, int revstart, TQString revKindStart, int revend, TQString revKindEnd )
{
KURL servURL = m_part->baseURL();
if ( servURL.isEmpty() ) servURL="kdevsvn+svn://blah/";
if ( ! servURL.protocol().startsWith( "kdevsvn+" ) ) {
servURL.setProtocol( "kdevsvn+" + servURL.protocol() ); //make sure it starts with "svn"
}
kdDebug(9036) << "servURL : " << servURL.prettyURL() << endl;
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
// prepare arguments
int cmd = 14;
s << cmd << url << (int)mode ;
s << revstart << revKindStart << revend << revKindEnd ;
SimpleJob * job = TDEIO::special(servURL, parms, false);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotBlameResult( TDEIO::Job * ) ) );
initProcessDlg( (TDEIO::Job*)job, url.prettyURL() , i18n("Subversion Blame") );
}
void subversionCore::add( const KURL::List& list ) {
KURL servURL = "kdevsvn+svn://blah/";
kdDebug(9036) << "Deleting servURL : " << servURL.prettyURL() << endl;
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
int cmd = 6;
s << cmd << list;
// add/delete/revert works on local copy. Don't need to show progress dialog
SimpleJob * job = TDEIO::special(servURL, parms, false);
job->setWindow( m_part->mainWindow()->main() );
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
}
void subversionCore::del( const KURL::List& list ) {
KURL servURL = "kdevsvn+svn://blah/";
kdDebug(9036) << "Deleting servURL : " << servURL.prettyURL() << endl;
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
int cmd = 7;
s << cmd << list;
// add/delete/revert works on local copy. Don't need to show progress dialog
SimpleJob * job = TDEIO::special(servURL, parms, false);
job->setWindow( m_part->mainWindow()->main() );
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
}
void subversionCore::revert( const KURL::List& list ) {
KURL servURL = "kdevsvn+svn://blah/";
kdDebug(9036) << "Reverting servURL : " << servURL.prettyURL() << endl;
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
int cmd = 8;
s << cmd << list;
SimpleJob * job = TDEIO::special(servURL, parms, false);
job->setWindow( m_part->mainWindow()->main() );
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
}
void subversionCore::checkout() {
svn_co checkoutDlg;
if ( checkoutDlg.exec() == TQDialog::Accepted ) {
//checkout :)
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
KURL servURL ( checkoutDlg.serverURL->url() );
wcPath = checkoutDlg.localDir->url() + "/" + checkoutDlg.newDir->text();
int cmd = 1;
int rev = -1;
s << cmd << servURL << KURL( wcPath ) << rev << TQString( "HEAD" );
servURL.setProtocol( "kdevsvn+" + servURL.protocol() ); //make sure it starts with "svn"
SimpleJob * job = TDEIO::special(servURL,parms, true);
job->setWindow( m_part->mainWindow()->main() );
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotEndCheckout( TDEIO::Job * ) ) );
}
}
void subversionCore::switchTree( const KURL &path, const KURL &repositUrl,
int revNum, const TQString &revKind, bool recurse )
{
KURL servURL = "kdevsvn+svn://blah/";
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
// prepare arguments
int cmd = 12;
s << cmd << path << repositUrl ;
s << recurse << revNum << revKind;
SimpleJob * job = TDEIO::special(servURL, parms, false);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
initProcessDlg( (TDEIO::Job*)job, repositUrl.prettyURL() , path.prettyURL() );
}
void subversionCore::switchRelocate( const KURL &path,
const KURL &currentUrl, const KURL &newUrl, bool recurse )
{
KURL servURL = "kdevsvn+svn://blah/";
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
// prepare arguments
int cmd = 16;
s << cmd << path << currentUrl << newUrl << recurse;
SimpleJob * job = TDEIO::special(servURL, parms, false);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
// this doesn't contact repository
}
void subversionCore::svnCopy( const KURL &src, int srcRev, const TQString &srcRevKind,
const KURL &dest )
{
KURL servURL = "kdevsvn+svn://blah/";
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
// prepare arguments
int cmd = 17;
s << cmd << src << srcRev << srcRevKind << dest;
SimpleJob * job = TDEIO::special(servURL, parms, false);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
initProcessDlg( (TDEIO::Job*)job, src.prettyURL(), dest.prettyURL() );
}
void subversionCore::merge( const KURL &src1, int rev1, TQString revKind1,
const KURL &src2, int rev2, TQString revKind2, const KURL &wc_path,
bool recurse, bool ignore_ancestry, bool force, bool dry_run )
{
KURL servURL = "kdevsvn+svn://blah/";
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
// prepare arguments
int cmd = 18;
s << cmd << src1 << rev1 << revKind1 << src2 << rev2 << revKind2 << wc_path;
s << recurse << ignore_ancestry << force << dry_run;
SimpleJob * job = TDEIO::special(servURL, parms, false);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
initProcessDlg( (TDEIO::Job*)job, src1.prettyURL() + "\n" + src2.prettyURL() ,
wc_path.prettyURL() );
}
bool subversionCore::clientInfo( KURL path_or_url, bool recurse, TQMap< KURL, SvnInfoHolder> &holderMap )
{
KURL servURL = "kdevsvn+svn://blah/";
TQByteArray parms;
TQDataStream s( parms, IO_WriteOnly );
int cmd = 15;
s << cmd << path_or_url << -1 << TQString("UNSPECIFIED") << -1 << TQString("UNSPECIFIED") << recurse;
SimpleJob *job = TDEIO::special( servURL, parms, false );
TQMap<TQString,TQString> ma;
TDEIO::NetAccess::synchronousRun(job, 0, 0, 0, &ma ); // synchronize
TQValueList<TQString> keys = ma.keys();
TQValueList<TQString>::Iterator begin = keys.begin(), end = keys.end(), it;
int curIdx, lastIdx;
TQRegExp rx( "([0-9]*)(.*)" );
for ( it = begin; it != end; /*++it*/) {
kdDebug(9036) << "METADATA key: " << *it << " value: " << ma[ *it ] << endl;
if ( rx.search( *it ) == -1 ) return false; // something is wrong ! :)
curIdx = lastIdx = rx.cap( 1 ).toInt();
SvnInfoHolder holder;
while ( curIdx == lastIdx ) {
if ( rx.cap( 2 ) == "PATH" )
holder.path = KURL( ma[ *it ] );
else if ( rx.cap( 2 ) == "URL" )
holder.url = KURL( ma[*it] );
else if ( rx.cap( 2 ) == "REV" )
holder.rev= ma[ *it ].toInt();
else if ( rx.cap( 2 ) == "KIND" )
holder.kind = ma[ *it ].toInt();
else if ( rx.cap( 2 ) == "REPOS_ROOT_URL" )
holder.reposRootUrl = KURL( ma[*it] );
else if ( rx.cap( 2 ) == "REPOS_UUID" )
holder.reposUuid = ma[ *it ];
++it;
if ( it == end )
break;
if ( rx.search( *it ) == -1 ) return false; // something is wrong ! :)
curIdx = rx.cap( 1 ).toInt();
}
holderMap.insert( holder.path, holder );
}
return true;;
}
void subversionCore::slotEndCheckout( TDEIO::Job * job ) {
if ( job->error() ) {
job->showErrorDialog( m_part->mainWindow()->main() );
emit checkoutFinished( TQString() );
} else
emit checkoutFinished(wcPath);
}
void subversionCore::slotResult( TDEIO::Job * job ) {
if ( job->error() ){
job->showErrorDialog( m_part->mainWindow()->main() );
if( job->error() == ERR_CANNOT_LAUNCH_PROCESS )
KMessageBox::error( m_part->mainWindow()->main(),
i18n("If you have just have installed a new version of TDevelop,"
" and the error message was 'unknown protocol kdevsvn+*',"
" try restarting TDE."
) );
return;
}
TDEIO::MetaData ma = job->metaData();
TQValueList<TQString> keys = ma.keys();
qHeapSort( keys );
TQValueList<TQString>::Iterator begin = keys.begin(), end = keys.end(), it;
for ( it = begin; it != end; ++it ) {
// kdDebug(9036) << "METADATA : " << *it << ":" << ma[ *it ] << endl;
if ( ( *it ).endsWith( "string" ) ) {
m_part->mainWindow()->raiseView(processWidget());
processWidget()->append( ma[ *it ] );
}
//extra check to retrieve the diff output in case with run a diff command
if ( ( *it ).endsWith( "diffresult" ) ) {
diffresult << ma[ *it ];
}
}
}
void subversionCore::slotLogResult( TDEIO::Job * job )
{
if ( job->error() ){
job->showErrorDialog( m_part->mainWindow()->main() );
if( job->error() == ERR_CANNOT_LAUNCH_PROCESS )
KMessageBox::error( m_part->mainWindow()->main(),
i18n("If you have just have installed a new version of TDevelop,"
" and the error message was 'unknown protocol kdevsvn+*',"
" try restarting TDE."
) );
return;
}
TQValueList<SvnLogHolder> holderList;
TDEIO::MetaData ma = job->metaData();
TQValueList<TQString> keys = ma.keys();
TQRegExp rx( "([0-9]*)(.*)" );
int curIdx, lastIdx;
TQString requestedUrl;
for (TQValueList<TQString>::Iterator it = keys.begin(); it != keys.end(); /*++it*/ ){
if ( rx.search( *it ) == -1 ){
kdDebug(9036) << " Exiting loop at line " << __LINE__ <<endl;
return; // something is wrong ! :)
}
curIdx = lastIdx = rx.cap( 1 ).toInt();
SvnLogHolder logHolder;
while ( curIdx == lastIdx ) {
kdDebug(9036) << "svn log MetaData: " << *it << ":" << ma[ *it ] << endl;
if ( rx.cap( 2 ) == "author" )
logHolder.author = ma[*it];
else if ( rx.cap( 2 ) == "date" )
logHolder.date = ma[*it];
else if ( rx.cap( 2 ) == "logmsg" )
logHolder.logMsg = ma[*it];
else if ( rx.cap( 2 ) == "pathlist" )
logHolder.pathList = ma[*it];
else if ( rx.cap( 2 ) == "rev" )
logHolder.rev = ma[*it];
else if ( rx.cap( 2 ) == "requrl" )
requestedUrl = ma[*it];
++it;
if ( it == keys.end() )
break;
if ( rx.search( *it ) == -1 ){
kdDebug(9036) << " Exiting loop at line " << __LINE__ <<endl;
break; // something is wrong ! :)
}
curIdx = rx.cap( 1 ).toInt();
}//end of while
holderList.append( logHolder );
}
processWidget()->showLogResult( &holderList, requestedUrl );
m_part->mainWindow()->raiseView(processWidget());
}
void subversionCore::slotBlameResult( TDEIO::Job * job )
{
if ( job->error() ){
job->showErrorDialog( m_part->mainWindow()->main() );
if( job->error() == ERR_CANNOT_LAUNCH_PROCESS )
KMessageBox::error( m_part->mainWindow()->main(),
i18n("If you have just have installed a new version of TDevelop,"
" and the error message was 'unknown protocol kdevsvn+*',"
" try restarting TDE."
) );
return;
}
TQValueList<SvnBlameHolder> blameList;
TDEIO::MetaData ma = job->metaData();
TQValueList<TQString> keys = ma.keys();
TQRegExp rx( "([0-9]*)(.*)" );
int curIdx, lastIdx;
for (TQValueList<TQString>::Iterator it = keys.begin(); it != keys.end(); /*++it*/ ){
if ( rx.search( *it ) == -1 ){
kdDebug(9036) << " Exiting loop at line " << __LINE__ <<endl;
return; // something is wrong ! :)
}
// if metadata has action key, that means a notification for svn_wc_notify_blame_completed
// Thus, consume this notification
if ( rx.cap( 2 ) == "action" ){
curIdx = lastIdx = rx.cap( 1 ).toInt();
while ( curIdx == lastIdx ){
++it;
if ( it == keys.end() ) break;
if ( rx.search( *it ) == -1 ) continue; // something is wrong
curIdx = rx.cap( 1 ).toInt();
}
continue;
}
// get actual blame data
curIdx = lastIdx = rx.cap( 1 ).toInt();
SvnBlameHolder blameHolder;
while ( curIdx == lastIdx ) {
kdDebug(9036) << "svn blame MetaData: " << *it << ":" << ma[ *it ] << endl;
if ( rx.cap( 2 ) == "LINE" )
blameHolder.line= (ma[*it]).toInt();
else if ( rx.cap( 2 ) == "REV" )
blameHolder.rev = (ma[*it]).toLongLong();
else if ( rx.cap( 2 ) == "AUTHOR" )
blameHolder.author= ma[*it];
else if ( rx.cap( 2 ) == "DATE" )
blameHolder.date= ma[*it];
else if ( rx.cap( 2 ) == "CONTENT" )
blameHolder.content = ma[*it];
++it;
if ( it == keys.end() )
break;
if ( rx.search( *it ) == -1 ){
kdDebug(9036) << " Exiting loop at line " << __LINE__ <<endl;
break; // something is wrong ! :)
}
curIdx = rx.cap( 1 ).toInt();
}//end of while
blameList.append( blameHolder );
// blameList.insert( blameHolder.line, blameHolder );
}
processWidget()->showBlameResult( &blameList );
m_part->mainWindow()->raiseView(processWidget());
}
void subversionCore::slotDiffResult( TDEIO::Job * job )
{
if ( job->error() ){
job->showErrorDialog( m_part->mainWindow()->main() );
if( job->error() == ERR_CANNOT_LAUNCH_PROCESS )
KMessageBox::error( m_part->mainWindow()->main(),
i18n("If you have just have installed a new version of TDevelop,"
" and the error message was 'unknown protocol kdevsvn+*',"
" try restarting TDE."
) );
return;
}
TDEIO::MetaData ma = job->metaData();
TQValueList<TQString> keys = ma.keys();
qHeapSort( keys );
TQValueList<TQString>::Iterator begin = keys.begin(), end = keys.end(), it;
TQStringList diffList;
for ( it = begin; it != end; ++it ) {
// kdDebug(9036) << "METADATA : " << *it << ":" << ma[ *it ] << endl;
if ( ( *it ).endsWith( "diffresult" ) ) {
diffList << ma[ *it ];
}
}
if ( diffList.count() > 0 ) {
//check kompare is available
if ( !TDEStandardDirs::findExe( "kompare" ).isNull() ) {
KTempFile *tmp = new KTempFile;
tmp->setAutoDelete(true);
TQTextStream *stream = tmp->textStream();
stream->setCodec( TQTextCodec::codecForName( "utf8" ) );
for ( TQStringList::Iterator it2 = diffList.begin();it2 != diffList.end() ; ++it2 ) {
( *stream ) << ( *it2 ) << "\n";
}
tmp->close();
TDEProcess *p = new TDEProcess;
*p << "kompare" << "-n" << "-o" << tmp->name();
p->start();
} else { //else do it with message box
KMessageBox::information( NULL, i18n("You do not have kompare installed. We recommend you install kompare to view differences graphically.") + "\nhttp://www.caffeinated.me.uk/kompare/" , TQString() , "userDoesNotWantKompare" );
Subversion_Diff df;
for ( TQStringList::Iterator it2 = diffList.begin();it2 != diffList.end() ; ++it2 ) {
df.text->append( *it2 );
}
TQFont f = df.font();
f.setFixedPitch( true );
df.text->setFont( f );
df.exec();
}
}
else{
KMessageBox::information( 0, i18n("No subversion differences") );
}
}
void subversionCore::initProcessDlg( TDEIO::Job *job, const TQString &src, const TQString &dest )
{
SvnProgressDlg *progress = new SvnProgressDlg( true );
progress->setSourceUrl( src );
progress->setDestUrl( dest );
progress->setJob( job );
connect( job, TQT_SIGNAL( totalSize(TDEIO::Job*, TDEIO::filesize_t) ),
progress, TQT_SLOT( slotTotalSize (TDEIO::Job*, TDEIO::filesize_t) ) );
connect( job, TQT_SIGNAL( processedSize(TDEIO::Job*, TDEIO::filesize_t) ),
progress, TQT_SLOT( slotProcessedSize(TDEIO::Job*, TDEIO::filesize_t) ) );
}
void subversionCore::createNewProject( const TQString& // dirName
, const KURL& // importURL
, bool // init
) {
}
#include "subversion_core.moc"