From kde-i18n-doc Fri Dec 15 20:43:18 2006 From: Hasso Tepper Date: Fri, 15 Dec 2006 20:43:18 +0000 To: kde-i18n-doc Subject: Subversion 1.4 support for KBabel catalogmanager Message-Id: <200612152243.20074.hasso () kde ! org> X-MARC-Message: https://marc.info/?l=kde-i18n-doc&m=116621541906423 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_ojwgFEEHg+yjuj1" --Boundary-00=_ojwgFEEHg+yjuj1 Content-Type: text/plain; charset="iso-8859-15" Content-Transfer-Encoding: 7bit Content-Disposition: inline Attached patch implements subversion 1.4 support for catalogmanager. It's only briefly tested in my laptop which only has 1.4, so I don't really know whether older versions still work, but they should. It's quickly hacked together during some hours and I don't have really time to polish it, but I think that idea is correct (parsing "svn status -v --xml" output) and any solution is better at the moment than no solution. If someone wants to improve/fix/etc it, feel free. Thanks goes to my coworker for kicking my ass ("It can do XML, man!!!") and to the Sebastian Trueg for lovely app (k3b) and for OutputCollector class I borrowed from it. If patch gets more testing and no objections, I can take care of committing it. Patch is against 3.5 branch of course. with my best wishes, -- Hasso Tepper KDE Estonian Team --Boundary-00=_ojwgFEEHg+yjuj1 Content-Type: text/x-diff; charset="iso-8859-15"; name="subversion-1.4.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="subversion-1.4.patch" Index: catalogmanager/libsvn/svnhandler.h =================================================================== --- catalogmanager/libsvn/svnhandler.h (revision 613839) +++ catalogmanager/libsvn/svnhandler.h (working copy) @@ -112,4 +112,27 @@ QMap map; }; +class SVNOutputCollector: public QObject +{ + Q_OBJECT + + public: + SVNOutputCollector( KProcess* ); + void setProcess( KProcess* ); + + const QString& output() const { return m_gatheredOutput; } + const QString& stderr() const { return m_stderrOutput; } + const QString& stdout() const { return m_stdoutOutput; } + + private slots: + void slotGatherStderr( KProcess*, char*, int ); + void slotGatherStdout( KProcess*, char*, int ); + + private: + QString m_gatheredOutput; + QString m_stderrOutput; + QString m_stdoutOutput; + KProcess* m_process; +}; + #endif // SVNHANDLER_H Index: catalogmanager/libsvn/svnhandler.cpp =================================================================== --- catalogmanager/libsvn/svnhandler.cpp (revision 613839) +++ catalogmanager/libsvn/svnhandler.cpp (working copy) @@ -50,10 +50,10 @@ #include #include #include +#include // project specific include files #include "svnhandler.h" - SVNHandler::SVNHandler( const QString& poBaseDir, const QString& potBaseDir ) { setPOBaseDir( poBaseDir ); @@ -126,19 +126,78 @@ QFileInfo info( fn ); - // check if '.svn/entries' exists and can be read + // check if '.svn/entries' exists. QFile entries( info.dir( true ).path( ) + "/.svn/entries" ); if ( !entries.exists() ) return NOT_IN_SVN; - - if ( !entries.open( IO_ReadOnly ) ) - return ERROR_IN_WC; // we already know that it is a repository + KProcess proc; + SVNOutputCollector out( &proc ); + + proc << "svn" << "status" << "-v" << "--xml" << info.absFilePath(); + + if( !proc.start( KProcess::Block, KProcess::Stdout ) ) + return ERROR_IN_WC; + QDomDocument doc; QString errorMsg; int errorLine, errorCol; + QDomNodeList nodelist; + QDomNode node; + QDomElement entry, wcStatus; + // Parse the output. + if ( !doc.setContent( out.output(), &errorMsg, &errorLine, &errorCol ) ) { + kdDebug(8109) << "Cannot parse \"svn status -v --xml\" output for" + << filename << endl << "Line: " << errorLine << " Column: " + << errorCol << " Error: " << errorMsg << endl; + goto no_status_xml; + } + + // There should be only one "entry" element. If it doesn't exist, path + // isn't repo path at all. + nodelist = doc.elementsByTagName("entry"); + if (nodelist.count() < 1) + return NOT_IN_SVN; + + entry = nodelist.item(0).toElement(); + + // Shouldn't fail, but just in case there is some weird error. + if ( entry.attributeNode("path").value() != info.absFilePath() ) + return ERROR_IN_WC; + + for ( node = entry.firstChild(); !node.isNull(); node = node.nextSibling() ) { + if ( !node.isElement() ) + continue; + if (node.toElement().tagName() == "wc-status") + break; + } + + if ( node.isNull() ) + return ERROR_IN_WC; + + wcStatus = node.toElement(); + + if ( wcStatus.attributeNode("item").value() == "normal" ) + return UP_TO_DATE; + if ( wcStatus.attributeNode("item").value() == "modified" ) + return LOCALLY_MODIFIED; + if ( wcStatus.attributeNode("item").value() == "conflicted" ) + return CONFLICT; + if ( wcStatus.attributeNode("item").value() == "unversioned" ) + return NOT_IN_SVN; + if ( wcStatus.attributeNode("item").value() == "added" ) + return LOCALLY_ADDED; + if ( wcStatus.attributeNode("item").value() == "deleted" ) + return LOCALLY_REMOVED; + + return ERROR_IN_WC; + +no_status_xml: + if ( !entries.open( IO_ReadOnly ) ) + return ERROR_IN_WC; // we already know that it is a repository + // Parse the entries file if ( !doc.setContent( &entries, &errorMsg, &errorLine, &errorCol ) ) { kdDebug() << "Cannot parse .svn/entries file for " << filename << endl @@ -439,7 +498,42 @@ return status == LOCALLY_MODIFIED || status == NOT_IN_SVN; } +SVNOutputCollector::SVNOutputCollector( KProcess* p ) + : m_process(0) +{ + setProcess( p ); +} +void SVNOutputCollector::setProcess( KProcess* p ) +{ + if( m_process ) + m_process->disconnect( this ); + + m_process = p; + if( p ) { + connect( p, SIGNAL(receivedStdout(KProcess*, char*, int)), + this, SLOT(slotGatherStdout(KProcess*, char*, int)) ); + connect( p, SIGNAL(receivedStderr(KProcess*, char*, int)), + this, SLOT(slotGatherStderr(KProcess*, char*, int)) ); + } + + m_gatheredOutput.truncate( 0 ); + m_stderrOutput.truncate( 0 ); + m_stdoutOutput.truncate( 0 ); +} + +void SVNOutputCollector::slotGatherStderr( KProcess*, char* data, int len ) +{ + m_gatheredOutput.append( QString::fromLocal8Bit( data, len ) ); + m_stderrOutput.append( QString::fromLocal8Bit( data, len ) ); +} + +void SVNOutputCollector::slotGatherStdout( KProcess*, char* data, int len ) +{ + m_gatheredOutput.append( QString::fromLocal8Bit( data, len ) ); + m_stdoutOutput.append( QString::fromLocal8Bit( data, len ) ); +} + #include "svnhandler.moc" // kate: space-indent on; indent-width 2; replace-tabs on; --Boundary-00=_ojwgFEEHg+yjuj1--