[Kbabel] branches/KDE/3.5/kdesdk/kbabel/catalogmanager/libsvn

Hasso Tepper hasso at kde.org
Tue Dec 19 09:37:07 CET 2006


SVN commit 614865 by hasso:

As I got no objections and some users even tested it (I really appreciate
this), I hope I'll not be killed because of committing this - subversion
1.4 support for catalogmanager.

BUG:135795
CCMAIL:kde-i18n-doc at kde.org
CCMAIL:kbabel at kde.org
CCMAIL:kde-et at linux.ee



 M  +104 -5    svnhandler.cpp  
 M  +23 -0     svnhandler.h  


--- branches/KDE/3.5/kdesdk/kbabel/catalogmanager/libsvn/svnhandler.cpp #614864:614865
@@ -50,10 +50,10 @@
 #include <kmessagebox.h>
 #include <ktempfile.h>
 #include <kdebug.h>
+#include <kprocess.h>
 // project specific include files
 #include "svnhandler.h"
 
-
 SVNHandler::SVNHandler( const QString& poBaseDir, const QString& potBaseDir )
 {
   setPOBaseDir( poBaseDir );
@@ -126,19 +126,83 @@
 
   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;
+  // TODO Ignored entry should have separate return value probably.
+  if ( wcStatus.attributeNode("item").value() == "ignored" )
+    return NOT_IN_SVN;
+  if ( wcStatus.attributeNode("item").value() == "added" )
+    return LOCALLY_ADDED;
+  if ( wcStatus.attributeNode("item").value() == "deleted" )
+    return LOCALLY_REMOVED;
+  // TODO What to do with "missing", "incomplete", "replaced", "merged",
+  // "obstructed", "external"? Can these appear at all in our case?
+
+  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 +503,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;
--- branches/KDE/3.5/kdesdk/kbabel/catalogmanager/libsvn/svnhandler.h #614864:614865
@@ -112,4 +112,27 @@
     QMap<QString,QString> 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


More information about the kbabel mailing list