[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-i18n-doc
Subject:    Subversion 1.4 support for KBabel catalogmanager
From:       Hasso Tepper <hasso () kde ! org>
Date:       2006-12-15 20:43:18
Message-ID: 200612152243.20074.hasso () kde ! org
[Download RAW message or body]

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

["subversion-1.4.patch" (text/x-diff)]

Index: catalogmanager/libsvn/svnhandler.h
===================================================================
--- catalogmanager/libsvn/svnhandler.h	(revision 613839)
+++ catalogmanager/libsvn/svnhandler.h	(working copy)
@@ -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
Index: catalogmanager/libsvn/svnhandler.cpp
===================================================================
--- catalogmanager/libsvn/svnhandler.cpp	(revision 613839)
+++ catalogmanager/libsvn/svnhandler.cpp	(working copy)
@@ -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,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;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic