summaryrefslogtreecommitdiffstats
path: root/src/kiosvn
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-15 17:32:48 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-15 17:32:48 +0000
commite2f541c98dfa4081fa3ab3d28f08ea2309281884 (patch)
treecb721a55bc88753ddeb9754dc98ef45e2850ce30 /src/kiosvn
downloadtdesvn-e2f541c98dfa4081fa3ab3d28f08ea2309281884.tar.gz
tdesvn-e2f541c98dfa4081fa3ab3d28f08ea2309281884.zip
Added KDE3 version of kdesvn
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kdesvn@1103685 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/kiosvn')
-rw-r--r--src/kiosvn/CMakeLists.txt26
-rw-r--r--src/kiosvn/kiobytestream.cpp63
-rw-r--r--src/kiosvn/kiobytestream.h66
-rw-r--r--src/kiosvn/kiolistener.cpp408
-rw-r--r--src/kiosvn/kiolistener.h83
-rw-r--r--src/kiosvn/kiosvn.cpp954
-rw-r--r--src/kiosvn/kiosvn.h120
-rw-r--r--src/kiosvn/ksvn+file.protocol39
-rw-r--r--src/kiosvn/ksvn+http.protocol39
-rw-r--r--src/kiosvn/ksvn+https.protocol39
-rw-r--r--src/kiosvn/ksvn+ssh.protocol39
-rw-r--r--src/kiosvn/ksvn.protocol39
-rw-r--r--src/kiosvn/svn+file.protocol39
-rw-r--r--src/kiosvn/svn+http.protocol39
-rw-r--r--src/kiosvn/svn+https.protocol39
-rw-r--r--src/kiosvn/svn+ssh.protocol39
-rw-r--r--src/kiosvn/svn.protocol39
17 files changed, 2110 insertions, 0 deletions
diff --git a/src/kiosvn/CMakeLists.txt b/src/kiosvn/CMakeLists.txt
new file mode 100644
index 0000000..5cce1af
--- /dev/null
+++ b/src/kiosvn/CMakeLists.txt
@@ -0,0 +1,26 @@
+INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/src/svnqt
+${CMAKE_BINARY_DIR}/src/ksvnwidgets)
+
+SET(kiosvn_src kiosvn.cpp kiolistener.cpp kiobytestream.cpp ../ksvnwidgets/pwstorage.cpp)
+FILE(GLOB hdr RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h")
+
+KDE3_ADD_KPART(kio_ksvn ${kiosvn_src} ${hdr})
+
+TARGET_LINK_LIBRARIES(kio_ksvn
+ svnqt
+ kdesvnhelpers
+ kdesvncfgreader
+ ${QT_AND_KDECORE_LIBS}
+ ${KDE3_UI_LIBRARY} ${KDE3_DCOP_LIBRARY} ${KDE3_KIO_LIBRARY} ${KDE3_WALLET_LIBRARY})
+
+SET_TARGET_PROPERTIES(kio_ksvn
+ PROPERTIES
+ LINK_FLAG "${LINK_NO_UNDEFINED} ${_BASE_LDADD}")
+
+INSTALL(TARGETS kio_ksvn
+ LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR})
+
+FILE(GLOB PROTFILES *.protocol)
+
+INSTALL(FILES ${PROTFILES}
+ DESTINATION ${SERVICES_INSTALL_DIR})
diff --git a/src/kiosvn/kiobytestream.cpp b/src/kiosvn/kiobytestream.cpp
new file mode 100644
index 0000000..ff10a6a
--- /dev/null
+++ b/src/kiosvn/kiobytestream.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * 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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "kiobytestream.h"
+
+KioByteStream::KioByteStream(StreamWrittenCb*aCb,const QString&filename)
+ : svn::stream::SvnStream(false,true,0L),
+ m_Cb(aCb),m_Written(0),
+ m_mimeSend(false),m_Filename(filename)
+{
+ m_MessageTick.start();
+}
+
+KioByteStream::~KioByteStream()
+{
+}
+
+bool KioByteStream::isOk() const
+{
+ return m_Cb != 0;
+}
+
+long KioByteStream::write(const char* data, const unsigned long max)
+{
+ bool forceInfo = !m_mimeSend;
+ if (m_Cb) {
+ if (!m_mimeSend) {
+ m_mimeSend = true;
+ array.setRawData(data, max);
+ KMimeMagicResult * result = KMimeMagic::self()->findBufferFileType(array,m_Filename);
+ m_Cb->streamSendMime(result);
+ array.resetRawData(data, max);
+ m_Cb->streamTotalSizeNull();
+ }
+ array.setRawData(data, max);
+ m_Cb->streamPushData(array);
+ array.resetRawData(data, max);
+
+ m_Written+=max;
+ if (m_MessageTick.elapsed() >=100 || forceInfo) {
+ m_Cb->streamWritten(m_Written);
+ m_MessageTick.restart();
+ }
+ return max;
+ }
+ return -1;
+}
diff --git a/src/kiosvn/kiobytestream.h b/src/kiosvn/kiobytestream.h
new file mode 100644
index 0000000..8e62155
--- /dev/null
+++ b/src/kiosvn/kiobytestream.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * 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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef KIOBYTESTREAM_H
+#define KIOBYTESTREAM_H
+
+#include "src/svnqt/svnstream.hpp"
+
+#include <kio/global.h>
+#include <kmimetype.h>
+#include <kmimemagic.h>
+#include <qbuffer.h>
+#include <qdatetime.h>
+
+class StreamWrittenCb
+{
+public:
+ StreamWrittenCb(){}
+ virtual ~StreamWrittenCb(){}
+ virtual void streamWritten(const KIO::filesize_t current) = 0;
+ virtual void streamPushData(QByteArray)=0;
+ virtual void streamSendMime(KMimeMagicResult*mt)=0;
+ virtual void streamTotalSizeNull()=0;
+};
+
+/**
+ @author Rajko Albrecht
+*/
+class KioByteStream : public svn::stream::SvnStream
+{
+public:
+ KioByteStream(StreamWrittenCb*,const QString&filename);
+
+ ~KioByteStream();
+
+ virtual bool isOk() const;
+ virtual long write(const char* data, const unsigned long max);
+
+ KIO::filesize_t written(){return m_Written;}
+
+protected:
+ StreamWrittenCb*m_Cb;
+ KIO::filesize_t m_Written;
+ bool m_mimeSend;
+ QString m_Filename;
+ QByteArray array;
+ QTime m_MessageTick;
+};
+
+#endif
diff --git a/src/kiosvn/kiolistener.cpp b/src/kiosvn/kiolistener.cpp
new file mode 100644
index 0000000..f3b7b68
--- /dev/null
+++ b/src/kiosvn/kiolistener.cpp
@@ -0,0 +1,408 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * 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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "kiolistener.h"
+#include "kiosvn.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <dcopclient.h>
+
+namespace KIO {
+
+KioListener::KioListener(KIO::kio_svnProtocol*_par)
+ : svn::ContextListener(),m_notifyCounter(0),m_External(false),m_HasChanges(false),m_FirstTxDelta(false),m_Canceld(false)
+{
+ par = _par;
+}
+
+
+KioListener::~KioListener()
+{
+}
+
+
+
+
+/*!
+ \fn KioListener::contextCancel()
+ */
+bool KioListener::contextCancel()
+{
+ return par->wasKilled()||m_Canceld;
+}
+
+
+/*!
+ \fn KioListener::contextGetLogMessage (QString & msg)
+ */
+bool KioListener::contextGetLogMessage (QString & msg,const svn::CommitItemList&_items)
+{
+#if 1
+ QByteArray reply;
+ QByteArray params;
+ QCString replyType;
+ QDataStream stream(params,IO_WriteOnly);
+
+ if (_items.count()>0) {
+ QMap<QString,QString> list;
+ for (unsigned i = 0;i<_items.count();++i) {
+ if (_items[i].path().isEmpty()) {
+ list[_items[i].url()]=QChar(_items[i].actionType());
+ } else {
+ list[_items[i].path()]=QChar(_items[i].actionType());
+ }
+ }
+ stream << list;
+ if (!par->dcopClient()->call("kded","kdesvnd","get_logmsg(QMap<QString,QString>)",params,replyType,reply)) {
+ msg = "Communication with dcop failed";
+ kdWarning()<<msg<<endl;
+ return false;
+ }
+ } else {
+ if (!par->dcopClient()->call("kded","kdesvnd","get_logmsg()",params,replyType,reply)) {
+ msg = "Communication with dcop failed";
+ kdWarning()<<msg<<endl;
+ return false;
+ }
+ }
+
+ if (replyType!="QStringList") {
+ msg = "Wrong reply type";
+ kdWarning()<<msg<<endl;
+ return false;
+ }
+ QDataStream stream2(reply,IO_ReadOnly);
+ QStringList lt;
+ stream2>>lt;
+ if (lt.count()!=1) {
+ msg = "Wrong or missing log (may cancel pressed).";
+ kdDebug()<< msg << endl;
+ return false;
+ }
+ msg = lt[0];
+#else
+ msg = "Made with a kio::svn client";
+#endif
+ return true;
+}
+
+/*! the content of that method is taken from the notify in kio::svn in KDE SDK */
+/* this moment we don't use it full 'cause not all is made via KIO */
+void KioListener::contextNotify (const char * path,svn_wc_notify_action_t action,svn_node_kind_t kind ,const char * mime_type ,svn_wc_notify_state_t content_state, svn_wc_notify_state_t prop_state,svn_revnum_t revision)
+{
+ if (par->wasKilled()) {
+ return;
+ }
+ QString userstring;
+
+ switch(action) {
+ case svn_wc_notify_add:
+ {
+ if (mime_type && (svn_mime_type_is_binary (mime_type)))
+ userstring = i18n( "A (bin) %1" ).arg( path );
+ else
+ userstring = i18n( "A %1" ).arg( path );
+ break;
+ }
+ break;
+ case svn_wc_notify_copy: //copy
+ break;
+ case svn_wc_notify_delete: //delete
+ m_HasChanges = TRUE;
+ userstring = i18n( "D %1" ).arg( path );
+ break;
+ case svn_wc_notify_restore : //restore
+ userstring=i18n( "Restored %1." ).arg( path );
+ break;
+ case svn_wc_notify_revert : //revert
+ userstring=i18n( "Reverted %1." ).arg( path );
+ break;
+ case svn_wc_notify_failed_revert: //failed revert
+ userstring=i18n( "Failed to revert %1.\nTry updating instead." ).arg( path );
+ break;
+ case svn_wc_notify_resolved: //resolved
+ userstring=i18n( "Resolved conflicted state of %1." ).arg( path );
+ break;
+ case svn_wc_notify_skip: //skip
+ if ( content_state == svn_wc_notify_state_missing )
+ userstring=i18n("Skipped missing target %1.").arg( path );
+ else
+ userstring=i18n("Skipped %1.").arg( path );
+ break;
+ case svn_wc_notify_update_delete: //update_delete
+ m_HasChanges = TRUE;
+ userstring=i18n( "D %1" ).arg( path );
+ break;
+ case svn_wc_notify_update_add: //update_add
+ m_HasChanges = TRUE;
+ userstring=i18n( "A %1" ).arg( path );
+ break;
+ case svn_wc_notify_update_update: //update_update
+ {
+ /* If this is an inoperative dir change, do no notification.
+ An inoperative dir change is when a directory gets closed
+ without any props having been changed. */
+ if (! ((kind == svn_node_dir)
+ && ((prop_state == svn_wc_notify_state_inapplicable)
+ || (prop_state == svn_wc_notify_state_unknown)
+ || (prop_state == svn_wc_notify_state_unchanged)))) {
+ m_HasChanges = TRUE;
+
+ if (kind == svn_node_file) {
+ if (content_state == svn_wc_notify_state_conflicted)
+ userstring = "C";
+ else if (content_state == svn_wc_notify_state_merged)
+ userstring = "G";
+ else if (content_state == svn_wc_notify_state_changed)
+ userstring = "U";
+ }
+
+ if (prop_state == svn_wc_notify_state_conflicted)
+ userstring += "C";
+ else if (prop_state == svn_wc_notify_state_merged)
+ userstring += "G";
+ else if (prop_state == svn_wc_notify_state_changed)
+ userstring += "U";
+ else
+ userstring += " ";
+
+ if (! ((content_state == svn_wc_notify_state_unchanged
+ || content_state == svn_wc_notify_state_unknown)
+ && (prop_state == svn_wc_notify_state_unchanged
+ || prop_state == svn_wc_notify_state_unknown)))
+ userstring += QString( " " ) + path;
+ }
+ break;
+ }
+ case svn_wc_notify_update_completed: //update_completed
+ {
+ if (!m_External) {
+ if (SVN_IS_VALID_REVNUM(revision)) {
+ userstring = i18n("Finished at revision %1.").arg(revision);
+ } else {
+ userstring = i18n("Finished.");
+ }
+ } else {
+ if (SVN_IS_VALID_REVNUM(revision)) {
+ userstring = i18n("Finished external at revision %1.").arg(revision);
+ } else {
+ userstring = i18n("Finished external.");
+ }
+ }
+ }
+ if (m_External)
+ m_External = FALSE;
+ break;
+ case svn_wc_notify_update_external: //update_external
+ m_External = TRUE;
+ userstring = i18n("Fetching external item into %1." ).arg( path );
+ break;
+ case svn_wc_notify_status_completed: //status_completed
+ if (SVN_IS_VALID_REVNUM (revision))
+ userstring = i18n( "Status against revision: %1.").arg( revision );
+ break;
+ case svn_wc_notify_status_external: //status_external
+ userstring = i18n("Performing status on external item at %1.").arg( path );
+ break;
+ case svn_wc_notify_commit_modified: //commit_modified
+ userstring = i18n( "Sending %1.").arg( path );
+ break;
+ case svn_wc_notify_commit_added: //commit_added
+ if (mime_type && svn_mime_type_is_binary (mime_type)) {
+ userstring = i18n( "Adding (bin) %1.").arg( path );
+ } else {
+ userstring = i18n( "Adding %1.").arg( path );
+ }
+ break;
+ case svn_wc_notify_commit_deleted: //commit_deleted
+ userstring = i18n( "Deleting %1.").arg( path );
+ break;
+ case svn_wc_notify_commit_replaced: //commit_replaced
+ userstring = i18n( "Replacing %1.").arg( path );
+ break;
+ case svn_wc_notify_commit_postfix_txdelta: //commit_postfix_txdelta
+ if (!m_FirstTxDelta) {
+ m_FirstTxDelta = TRUE;
+ // check fullstops!
+ userstring=i18n("Transmitting file data ");
+ } else {
+ userstring=".";
+ }
+ break;
+
+ break;
+ case svn_wc_notify_blame_revision: //blame_revision
+ break;
+ default:
+ break;
+ }
+ par->setMetaData(QString::number(counter()).rightJustify( 10,'0' )+ "path" , QString::FROMUTF8( path ));
+ par->setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "action", QString::number( action ));
+ par->setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "kind", QString::number( kind ));
+ par->setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "mime_t", QString::FROMUTF8( mime_type ));
+ par->setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "content", QString::number( content_state ));
+ par->setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "prop", QString::number( prop_state ));
+ par->setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "rev", QString::number( revision ));
+ par->setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "string", userstring );
+ incCounter();
+}
+
+void KioListener::contextNotify (const svn_wc_notify_t *action)
+{
+ if (!action) return;
+// if (action->action<svn_wc_notify_locked) {
+ contextNotify(action->path,action->action,action->kind,action->mime_type,
+ action->content_state,action->prop_state,action->revision);
+// return;
+// }
+// QString aString = NotifyAction(action->action);
+}
+
+svn::ContextListener::SslServerTrustAnswer
+KioListener::contextSslServerTrustPrompt (const SslServerTrustData & data, apr_uint32_t & acceptedFailures)
+{
+ QByteArray reply;
+ QByteArray params;
+ QCString replyType;
+ QDataStream stream(params,IO_WriteOnly);
+ stream << data.hostname
+ << data.fingerprint
+ << data.validFrom
+ << data.validUntil
+ << data.issuerDName
+ << data.realm;
+
+ if (!par->dcopClient()->call("kded","kdesvnd",
+ "get_sslaccept(QString,QString,QString,QString,QString,QString)",
+ params,replyType,reply)) {
+ kdWarning()<<"Communication with dcop failed"<<endl;
+ return DONT_ACCEPT;
+ }
+ if (replyType!="int") {
+ kdWarning()<<"Wrong reply type"<<endl;
+ return DONT_ACCEPT;
+ }
+ QDataStream stream2(reply,IO_ReadOnly);
+ int res;
+ stream2>>res;
+ switch (res) {
+ case -1:
+ return DONT_ACCEPT;
+ break;
+ case 1:
+ return ACCEPT_PERMANENTLY;
+ break;
+ default:
+ case 0:
+ return ACCEPT_TEMPORARILY;
+ break;
+ }
+ /* avoid compiler warnings */
+ return ACCEPT_TEMPORARILY;
+}
+
+bool KioListener::contextLoadSslClientCertPw(QString&password,const QString&realm)
+{
+ return PwStorage::self()->getCertPw(realm,password);
+}
+
+bool KioListener::contextSslClientCertPrompt (QString & certFile)
+{
+ QByteArray reply;
+ QByteArray params;
+ QCString replyType;
+ if (!par->dcopClient()->call("kded","kdesvnd",
+ "get_sslclientcertfile()",
+ params,replyType,reply)) {
+ kdWarning()<<"Communication with dcop failed"<<endl;
+ return false;
+ }
+ if (replyType!="QString") {
+ kdWarning()<<"Wrong reply type"<<endl;
+ return false;
+ }
+ QDataStream stream2(reply,IO_ReadOnly);
+ stream2>>certFile;
+ if (certFile.isEmpty()) {
+ return false;
+ }
+ return true;
+}
+
+bool KioListener::contextSslClientCertPwPrompt (QString & password,
+ const QString & realm, bool & maySave)
+{
+ return false;
+}
+
+bool KioListener::contextGetSavedLogin (const QString & realm,QString & username,QString & password)
+{
+ PwStorage::self()->getLogin(realm,username,password);
+ return true;
+}
+
+bool KioListener::contextGetCachedLogin (const QString & realm,QString & username,QString & password)
+{
+ return true;
+}
+
+bool KioListener::contextGetLogin (const QString & realm, QString & username, QString & password, bool & maySave)
+{
+ QByteArray reply;
+ QByteArray params;
+ QCString replyType;
+
+ QDataStream stream(params,IO_WriteOnly);
+ stream << realm;
+ stream << username;
+
+ if (!par->dcopClient()->call("kded","kdesvnd","get_login(QString,QString)",params,replyType,reply)) {
+ kdWarning()<<"Communication with dcop failed"<<endl;
+ return false;
+ }
+ if (replyType!="QStringList") {
+ kdWarning()<<"Wrong reply type"<<endl;
+ return false;
+ }
+ QDataStream stream2(reply,IO_ReadOnly);
+ QStringList lt;
+ stream2>>lt;
+ if (lt.count()!=3) {
+ kdDebug()<<"Wrong or missing auth list (may cancel pressed)." << endl;
+ return false;
+ }
+ username = lt[0];
+ password = lt[1];
+ maySave = lt[2]=="true";
+ return true;
+}
+
+
+/*!
+ \fn KioListener::contextProgress(long long int current, long long int max)
+ */
+void KioListener::contextProgress(long long int cur, long long int max)
+{
+ if (par) {
+ par->contextProgress(cur,max);
+ }
+}
+
+} // namespace KIO
diff --git a/src/kiosvn/kiolistener.h b/src/kiosvn/kiolistener.h
new file mode 100644
index 0000000..96a1629
--- /dev/null
+++ b/src/kiosvn/kiolistener.h
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * 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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef KIOLISTENER_H
+#define KIOLISTENER_H
+
+#include "src/svnqt/context_listener.hpp"
+#include "src/ksvnwidgets/pwstorage.h"
+
+namespace KIO {
+ class SlaveBase;
+ class kio_svnProtocol;
+
+/**
+@author Rajko Albrecht
+*/
+class KioListener : public svn::ContextListener
+{
+public:
+ KioListener(KIO::kio_svnProtocol*_par);
+ virtual ~KioListener();
+
+ /* context-listener methods */
+ virtual bool contextGetLogin (const QString & realm,
+ QString & username,
+ QString & password,
+ bool & maySave);
+ virtual bool contextGetSavedLogin (const QString & realm,QString & username,QString & password);
+ virtual bool contextGetCachedLogin (const QString & realm,QString & username,QString & password);
+
+ virtual void contextNotify (const char *path,
+ svn_wc_notify_action_t action,
+ svn_node_kind_t kind,
+ const char *mime_type,
+ svn_wc_notify_state_t content_state,
+ svn_wc_notify_state_t prop_state,
+ svn_revnum_t revision);
+ virtual void contextNotify (const svn_wc_notify_t *action);
+
+ virtual bool contextCancel();
+ virtual bool contextGetLogMessage (QString & msg,const svn::CommitItemList&);
+ virtual SslServerTrustAnswer contextSslServerTrustPrompt (const SslServerTrustData & data,
+ apr_uint32_t & acceptedFailures);
+ virtual bool contextSslClientCertPrompt (QString & certFile);
+ virtual bool contextSslClientCertPwPrompt (QString & password,
+ const QString & realm, bool & maySave);
+ virtual bool contextLoadSslClientCertPw(QString&password,const QString&realm);
+ /* context listener virtuals end */
+ unsigned int counter()const{return m_notifyCounter;}
+ void incCounter(){++m_notifyCounter;}
+ virtual void contextProgress(long long int current, long long int max);
+
+ void setCancel(bool value){m_Canceld=value;}
+
+private:
+ KIO::kio_svnProtocol *par;
+
+protected:
+ unsigned int m_notifyCounter;
+ bool m_External;
+ bool m_HasChanges;
+ bool m_FirstTxDelta;
+ bool m_Canceld;
+};
+}
+
+#endif
diff --git a/src/kiosvn/kiosvn.cpp b/src/kiosvn/kiosvn.cpp
new file mode 100644
index 0000000..667d456
--- /dev/null
+++ b/src/kiosvn/kiosvn.cpp
@@ -0,0 +1,954 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * 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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "kdesvn-config.h"
+#include "kiosvn.h"
+#include "kiolistener.h"
+
+#include "src/svnqt/svnqttypes.hpp"
+#include "src/svnqt/dirent.hpp"
+#include "src/svnqt/url.hpp"
+#include "src/svnqt/status.hpp"
+#include "src/svnqt/targets.hpp"
+#include "src/svnqt/info_entry.hpp"
+#include "src/settings/kdesvnsettings.h"
+#include "src/helpers/sub2qt.h"
+#include "src/helpers/sshagent.h"
+
+#include <stdlib.h>
+#include <math.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kdemacros.h>
+#include <kmessagebox.h>
+#include <kinstance.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <ktempdir.h>
+#include <ksock.h>
+#include <dcopclient.h>
+#include <qcstring.h>
+#include <kmimetype.h>
+#include <krun.h>
+#include <qtextstream.h>
+
+#include <stdlib.h>
+#include <math.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+namespace KIO
+{
+
+class KioSvnData
+{
+public:
+ KioSvnData(kio_svnProtocol*);
+ virtual ~KioSvnData();
+
+ void reInitClient();
+
+ KioListener m_Listener;
+ bool first_done;
+ bool dispProgress;
+ svn::ContextP m_CurrentContext;
+ svn::Client* m_Svnclient;
+
+ svn::Revision urlToRev(const KURL&);
+
+};
+
+KioSvnData::KioSvnData(kio_svnProtocol*par)
+ : m_Listener(par),first_done(false)
+{
+ m_Svnclient=svn::Client::getobject(0,0);
+ m_CurrentContext = 0;
+ dispProgress = false;
+ reInitClient();
+}
+
+void KioSvnData::reInitClient()
+{
+ if (first_done) {
+ return;
+ }
+ SshAgent ag;
+ ag.querySshAgent();
+
+ first_done = true;
+ m_CurrentContext = new svn::Context();
+ m_CurrentContext->setListener(&m_Listener);
+ m_Svnclient->setContext(m_CurrentContext);
+}
+
+KioSvnData::~KioSvnData()
+{
+ m_Listener.setCancel(true);
+ /* wait a little bit */
+ sleep(1);
+ delete m_Svnclient;
+ m_CurrentContext->setListener(0L);
+ m_CurrentContext = 0;
+}
+
+svn::Revision KioSvnData::urlToRev(const KURL&url)
+{
+ QMap<QString,QString> q = url.queryItems();
+
+ /* we try to check if it is ssh and try to get a password for it */
+ QString proto = url.protocol();
+
+ if (proto.find("ssh")!=-1) {
+ SshAgent ag;
+ ag.addSshIdentities();
+ }
+
+ svn::Revision rev,tmp;
+ rev = svn::Revision::UNDEFINED;
+ if (q.find("rev")!=q.end()) {
+ QString v = q["rev"];
+ m_Svnclient->url2Revision(v,rev,tmp);
+ }
+ return rev;
+}
+
+
+kio_svnProtocol::kio_svnProtocol(const QCString &pool_socket, const QCString &app_socket)
+ : SlaveBase("kio_ksvn", pool_socket, app_socket),StreamWrittenCb()
+{
+ m_pData=new KioSvnData(this);
+ KGlobal::locale()->insertCatalogue("kdesvn");
+}
+
+kio_svnProtocol::~kio_svnProtocol()
+{
+ kdDebug()<<"Delete kio protocol"<<endl;
+ delete m_pData;
+}
+
+}
+
+extern "C"
+{
+ KDESVN_EXPORT int kdemain(int argc, char **argv);
+}
+
+int kdemain(int argc, char **argv)
+{
+ kdDebug()<<"kdemain" << endl;
+ KInstance instance( "kio_ksvn" );
+ // start the kdesvnd DCOP service
+ QString error;
+ QCString appId;
+
+ kdDebug(7101) << "*** Starting kio_ksvn " << endl;
+
+ if (argc != 4) {
+ kdDebug(7101) << "Usage: kio_ksvn protocol domain-socket1 domain-socket2" << endl;
+ exit(-1);
+ }
+
+ KIO::kio_svnProtocol slave(argv[2], argv[3]);
+ slave.dispatchLoop();
+
+ kdDebug(7101) << "*** kio_ksvn Done" << endl;
+ return 0;
+}
+
+namespace KIO
+{
+/*!
+ \fn kio_svnProtocol::listDir (const KURL&url)
+ */
+void kio_svnProtocol::listDir(const KURL&url)
+{
+ kdDebug() << "kio_svn::listDir(const KURL& url) : " << url.url() << endl ;
+ svn::DirEntries dlist;
+ svn::Revision rev = m_pData->urlToRev(url);
+ if (rev == svn::Revision::UNDEFINED) {
+ rev = svn::Revision::HEAD;
+ }
+
+ try {
+ dlist = m_pData->m_Svnclient->list(makeSvnUrl(url),rev,rev,svn::DepthImmediates,false);
+ } catch (const svn::ClientException&e) {
+ QString ex = e.msg();
+ kdDebug()<<ex<<endl;
+ error(KIO::ERR_CANNOT_ENTER_DIRECTORY,ex);
+ return;
+ }
+ KIO::UDSEntry entry;
+ totalSize(dlist.size());
+ for (unsigned int i=0; i < dlist.size();++i) {
+ if (!dlist[i] || dlist[i]->name().isEmpty()) {
+ continue;
+ }
+ QDateTime dt = svn::DateTime(dlist[i]->time());
+ if (createUDSEntry(dlist[i]->name(),
+ dlist[i]->lastAuthor(),
+ dlist[i]->size(),
+ dlist[i]->kind()==svn_node_dir?true:false,
+ dt.toTime_t(),
+ entry) ) {
+ listEntry(entry,false);
+ }
+ entry.clear();
+ }
+ listEntry(entry, true );
+ finished();
+}
+
+void kio_svnProtocol::stat(const KURL& url)
+{
+ kdDebug()<<"kio_svn::stat "<< url << endl;
+ svn::Revision rev = m_pData->urlToRev(url);
+ if (rev == svn::Revision::UNDEFINED) {
+ rev = svn::Revision::HEAD;
+ }
+ svn::Revision peg = rev;
+ bool dummy = false;
+ svn::InfoEntries e;
+ try {
+ e = m_pData->m_Svnclient->info(makeSvnUrl(url),svn::DepthEmpty,rev,peg);
+ } catch (const svn::ClientException&e) {
+ QString ex = e.msg();
+ kdDebug()<<ex<<endl;
+ error( KIO::ERR_SLAVE_DEFINED,ex);
+ return;
+ }
+
+ if (e.count()==0) {
+ dummy = true;
+/* finished();
+ return;*/
+ }
+
+ KIO::UDSEntry entry;
+ QDateTime dt;
+ if (dummy) {
+ createUDSEntry(url.filename(),"",0,true,dt.toTime_t(),entry);
+ } else {
+ dt = svn::DateTime(e[0].cmtDate());
+ if (e[0].kind()==svn_node_file) {
+ createUDSEntry(url.filename(),"",0,false,dt.toTime_t(),entry);
+ } else {
+ createUDSEntry(url.filename(),"",0,true,dt.toTime_t(),entry);
+ }
+ }
+ statEntry(entry);
+ finished();
+}
+
+void kio_svnProtocol::get(const KURL& url)
+{
+ kdDebug()<<"kio_svn::get "<< url << endl;
+ if (m_pData->m_Listener.contextCancel()) {
+ finished();
+ return;
+ }
+ svn::Revision rev = m_pData->urlToRev(url);
+ if (rev == svn::Revision::UNDEFINED) {
+ rev = svn::Revision::HEAD;
+ }
+ KioByteStream dstream(this,url.filename());
+ try {
+ m_pData->m_Svnclient->cat(dstream,makeSvnUrl(url),rev,rev);
+ } catch (const svn::ClientException&e) {
+ QString ex = e.msg();
+ kdDebug()<<ex<<endl;
+ error( KIO::ERR_SLAVE_DEFINED,"Subversion error "+ex);
+ finished();
+ return;
+ }
+ totalSize(dstream.written());
+ data(QByteArray()); // empty array means we're done sending the data
+ finished();
+}
+
+void kio_svnProtocol::mkdir(const KURL &url, int)
+{
+ kdDebug()<<"kio_svn::mkdir "<< url << endl;
+ svn::Revision rev = m_pData->urlToRev(url);
+ if (rev == svn::Revision::UNDEFINED) {
+ rev = svn::Revision::HEAD;
+ }
+ try {
+ svn::Path p(makeSvnUrl(url));
+ m_pData->m_Svnclient->mkdir(p,getDefaultLog());
+ }catch (const svn::ClientException&e) {
+ error( KIO::ERR_SLAVE_DEFINED,e.msg());
+ }
+ kdDebug()<<"kio_svn::mkdir finished " << url << endl;
+ finished();
+}
+
+void kio_svnProtocol::mkdir(const KURL::List &urls, int)
+{
+ svn::Pathes p;
+ for ( QValueListConstIterator<KURL> it = urls.begin(); it != urls.end() ; ++it ) {
+ p.append((*it).path());
+ }
+ try {
+ m_pData->m_Svnclient->mkdir(svn::Targets(p),getDefaultLog());
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ return;
+ }
+ finished();
+}
+
+void kio_svnProtocol::rename(const KURL&src,const KURL&target,bool force)
+{
+ kdDebug()<<"kio_svn::rename "<< src << " to " << target << endl;
+ QString msg;
+ m_pData->m_CurrentContext->setLogMessage(getDefaultLog());
+ try {
+ m_pData->m_Svnclient->move(makeSvnUrl(src),makeSvnUrl(target),force);
+ }catch (const svn::ClientException&e) {
+ error( KIO::ERR_SLAVE_DEFINED,e.msg());
+ }
+ kdDebug()<<"kio_svn::rename finished" << endl;
+ finished();
+}
+
+void kio_svnProtocol::copy(const KURL&src,const KURL&dest,int permissions,bool overwrite)
+{
+ Q_UNUSED(permissions);
+ Q_UNUSED(overwrite);
+ kdDebug()<<"kio_svn::copy "<< src << " to " << dest << endl;
+ svn::Revision rev = m_pData->urlToRev(src);
+ if (rev == svn::Revision::UNDEFINED) {
+ rev = svn::Revision::HEAD;
+ }
+ m_pData->dispProgress=true;
+ m_pData->m_CurrentContext->setLogMessage(getDefaultLog());
+ try {
+ m_pData->m_Svnclient->copy(makeSvnUrl(src),rev,makeSvnUrl(dest));
+ }catch (const svn::ClientException&e) {
+ error( KIO::ERR_SLAVE_DEFINED,e.msg());
+ }
+ m_pData->dispProgress=false;
+ kdDebug()<<"kio_svn::copy finished" << endl;
+ finished();
+}
+
+void kio_svnProtocol::del(const KURL&src,bool isfile)
+{
+ Q_UNUSED(isfile);
+ kdDebug()<<"kio_svn::del "<< src << endl;
+ //m_pData->reInitClient();
+ svn::Revision rev = m_pData->urlToRev(src);
+ if (rev == svn::Revision::UNDEFINED) {
+ rev = svn::Revision::HEAD;
+ }
+ m_pData->m_CurrentContext->setLogMessage(getDefaultLog());
+ try {
+ svn::Targets target(makeSvnUrl(src));
+ m_pData->m_Svnclient->remove(target,false);
+ } catch (const svn::ClientException&e) {
+ QString ex = e.msg();
+ kdDebug()<<ex<<endl;
+ error( KIO::ERR_SLAVE_DEFINED,ex);
+ }
+ kdDebug()<<"kio_svn::del finished" << endl;
+ finished();
+}
+
+bool kio_svnProtocol::getLogMsg(QString&t)
+{
+ svn::CommitItemList _items;
+ return m_pData->m_Listener.contextGetLogMessage(t,_items);
+}
+
+bool kio_svnProtocol::checkWc(const KURL&url)
+{
+ if (url.isEmpty()||!url.isLocalFile()) return false;
+ svn::Revision peg(svn_opt_revision_unspecified);
+ svn::Revision rev(svn_opt_revision_unspecified);
+ svn::InfoEntries e;
+ try {
+ e = m_pData->m_Svnclient->info(url.prettyURL(),svn::DepthEmpty,rev,peg);
+ } catch (const svn::ClientException&e) {
+ if (SVN_ERR_WC_NOT_DIRECTORY==e.apr_err())
+ {
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+QString kio_svnProtocol::makeSvnUrl(const KURL&url,bool check_Wc)
+{
+ QString res;
+ QString proto = svn::Url::transformProtokoll(url.protocol());
+ if (proto=="file" && check_Wc)
+ {
+ if (checkWc(url))
+ {
+ return url.path();
+ }
+ }
+
+ QStringList s = QStringList::split("://",res);
+ QString base = url.path();
+ QString host = url.host();
+ QString user = (url.hasUser()?url.user()+(url.hasPass()?":"+url.pass():""):"");
+ if (host.isEmpty()) {
+ res=proto+"://"+base;
+ } else {
+ res = proto+"://"+(user.isEmpty()?"":user+"@")+host+base;
+ }
+ if (base.isEmpty()) {
+ throw svn::ClientException(QString("'")+res+QString("' is not a valid subversion url"));
+ }
+ return res;
+}
+
+bool kio_svnProtocol::createUDSEntry( const QString& filename, const QString& user, long long int size, bool isdir, time_t mtime, KIO::UDSEntry& entry)
+{
+#if 0
+ kdDebug() << "MTime : " << ( long )mtime << endl;
+ kdDebug() << "UDS filename : " << filename << endl;
+ kdDebug()<< "UDS Size: " << size << endl;
+ kdDebug()<< "UDS Dir: " << isdir << endl;
+#endif
+ KIO::UDSAtom atom;
+ atom.m_uds = KIO::UDS_NAME;
+ atom.m_str = filename;
+ entry.append( atom );
+
+ atom.m_uds = KIO::UDS_FILE_TYPE;
+ atom.m_long = isdir ? S_IFDIR : S_IFREG;
+ entry.append( atom );
+
+ atom.m_uds = KIO::UDS_ACCESS;
+ atom.m_long = isdir?0777:0666;
+ entry.append(atom);
+
+
+ atom.m_uds = KIO::UDS_SIZE;
+ atom.m_long = size;
+ entry.append( atom );
+
+ atom.m_uds = KIO::UDS_MODIFICATION_TIME;
+ atom.m_long = mtime;
+ entry.append( atom );
+
+ atom.m_uds = KIO::UDS_USER;
+ atom.m_str = user;
+ entry.append( atom );
+
+ return true;
+}
+
+void kio_svnProtocol::special(const QByteArray& data)
+{
+ kdDebug()<<"kio_svnProtocol::special"<<endl;
+ QDataStream stream(data,IO_ReadOnly);
+ int tmp;
+ stream >> tmp;
+ kdDebug() << "kio_svnProtocol::special " << tmp << endl;
+ switch (tmp) {
+ case SVN_CHECKOUT:
+ {
+ KURL repository, wc;
+ int revnumber;
+ QString revkind;
+ stream >> repository;
+ stream >> wc;
+ stream >> revnumber;
+ stream >> revkind;
+ kdDebug(0) << "kio_svnProtocol CHECKOUT from " << repository.url() << " to " << wc.url() << " at " << revnumber << " or " << revkind << endl;
+ checkout( repository, wc, revnumber, revkind );
+ break;
+ }
+ case SVN_UPDATE:
+ {
+ KURL wc;
+ int revnumber;
+ QString revkind;
+ stream >> wc;
+ stream >> revnumber;
+ stream >> revkind;
+ kdDebug(0) << "kio_svnProtocol UPDATE " << wc.url() << " at " << revnumber << " or " << revkind << endl;
+ update(wc, revnumber, revkind );
+ break;
+ }
+ case SVN_COMMIT:
+ {
+ KURL::List wclist;
+ while ( !stream.atEnd() ) {
+ KURL tmp;
+ stream >> tmp;
+ wclist << tmp;
+ }
+ kdDebug(0) << "kio_svnProtocol COMMIT" << endl;
+ commit( wclist );
+ break;
+ }
+ case SVN_LOG:
+ {
+ kdDebug(0) << "kio_svnProtocol LOG" << endl;
+ int revstart, revend;
+ QString revkindstart, revkindend;
+ KURL::List targets;
+ stream >> revstart;
+ stream >> revkindstart;
+ stream >> revend;
+ stream >> revkindend;
+ while ( !stream.atEnd() ) {
+ KURL tmp;
+ stream >> tmp;
+ targets << tmp;
+ }
+ svnlog( revstart, revkindstart, revend, revkindend, targets );
+ break;
+ }
+ case SVN_IMPORT:
+ {
+ KURL wc,repos;
+ stream >> repos;
+ stream >> wc;
+ kdDebug(0) << "kio_ksvnProtocol IMPORT" << endl;
+ import(repos,wc);
+ break;
+ }
+ case SVN_ADD:
+ {
+ KURL wc;
+ kdDebug(0) << "kio_ksvnProtocol ADD" << endl;
+ stream >> wc;
+ add(wc);
+ break;
+ }
+ case SVN_DEL:
+ {
+ KURL::List wclist;
+ while ( !stream.atEnd() ) {
+ KURL tmp;
+ stream >> tmp;
+ wclist << tmp;
+ }
+ wc_delete(wclist);
+ break;
+ }
+ case SVN_REVERT:
+ {
+ KURL::List wclist;
+ while ( !stream.atEnd() ) {
+ KURL tmp;
+ stream >> tmp;
+ wclist << tmp;
+ }
+ kdDebug(7128) << "kio_svnProtocol REVERT" << endl;
+ revert(wclist);
+ break;
+ }
+ case SVN_STATUS:
+ {
+ KURL wc;
+ bool checkRepos=false;
+ bool fullRecurse=false;
+ stream >> wc;
+ stream >> checkRepos;
+ stream >> fullRecurse;
+ kdDebug(0) << "kio_svnProtocol STATUS" << endl;
+ status(wc,checkRepos,fullRecurse);
+ break;
+ }
+ case SVN_MKDIR:
+ {
+ KURL::List list;
+ stream >> list;
+ kdDebug(0) << "kio_svnProtocol MKDIR" << endl;
+ mkdir(list,0);
+ break;
+ }
+ case SVN_RESOLVE:
+ {
+ KURL url;
+ bool recurse;
+ stream >> url;
+ stream >> recurse;
+ kdDebug(7128) << "kio_svnProtocol RESOLVE" << endl;
+ wc_resolve(url,recurse);
+ break;
+ }
+ case SVN_SWITCH:
+ {
+ KURL wc,url;
+ bool recurse;
+ int revnumber;
+ QString revkind;
+ stream >> wc;
+ stream >> url;
+ stream >> recurse;
+ stream >> revnumber;
+ stream >> revkind;
+ kdDebug(7128) << "kio_svnProtocol SWITCH" << endl;
+ wc_switch(wc,url,recurse,revnumber,revkind);
+ break;
+ }
+ case SVN_DIFF:
+ {
+ KURL url1,url2;
+ int rev1, rev2;
+ bool recurse;
+ QString revkind1, revkind2;
+ stream >> url1;
+ stream >> url2;
+ stream >> rev1;
+ stream >> revkind1;
+ stream >> rev2;
+ stream >> revkind2;
+ stream >> recurse;
+ diff(url1,url2,rev1,revkind1,rev2,revkind2,recurse);
+ break;
+ }
+ default:
+ {kdDebug()<<"Unknown special" << endl;}
+ }
+ finished();
+}
+
+void kio_svnProtocol::update(const KURL&url,int revnumber,const QString&revkind)
+{
+ svn::Revision where(revnumber,revkind);
+ /* update is always local - so make a path instead URI */
+ svn::Path p(url.path());
+ try {
+ svn::Targets pathes(p.path());
+ // always update externals, too. (third last parameter)
+ // no unversioned items allowed (second last parameter)
+ // sticky depth (last parameter)
+ m_pData->m_Svnclient->update(pathes, where,svn::DepthInfinity,false,false,true);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ }
+}
+
+void kio_svnProtocol::status(const KURL&wc,bool cR,bool rec)
+{
+ svn::Revision where = svn::Revision::UNDEFINED;
+ svn::StatusEntries dlist;
+ try {
+ // rec all up noign
+ dlist = m_pData->m_Svnclient->status(wc.path(),rec?svn::DepthInfinity:svn::DepthEmpty,false,cR,false,where);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ return;
+ }
+ kdDebug()<<"Status got " << dlist.count() << " entries." << endl;
+ for (unsigned j=0;j<dlist.count();++j) {
+ if (!dlist[j]) {
+ continue;
+ }
+ //QDataStream stream(params, IO_WriteOnly);
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+"path",dlist[j]->path());
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+"text",QString::number(dlist[j]->textStatus()));
+ setMetaData(QString::number(m_pData->m_Listener.counter() ).rightJustify( 10,'0' )+ "prop",
+ QString::number(dlist[j]->propStatus()));
+ setMetaData(QString::number(m_pData->m_Listener.counter() ).rightJustify( 10,'0' )+ "reptxt",
+ QString::number(dlist[j]->reposTextStatus()));
+ setMetaData(QString::number(m_pData->m_Listener.counter() ).rightJustify( 10,'0' )+ "repprop",
+ QString::number(dlist[j]->reposPropStatus()));
+ setMetaData(QString::number(m_pData->m_Listener.counter() ).rightJustify( 10,'0' )+ "rev",
+ QString::number(dlist[j]->entry().cmtRev()));
+ m_pData->m_Listener.incCounter();
+ }
+}
+
+void kio_svnProtocol::commit(const KURL::List&url)
+{
+ /// @todo replace with direct call to kdesvn?
+ QByteArray reply;
+ QByteArray params;
+ QCString replyType;
+ QString msg;
+
+ if (!dcopClient()->call("kded","kdesvnd","get_logmsg()",params,replyType,reply)) {
+ msg = "Communication with dcop failed";
+ kdWarning()<<msg<<endl;
+ return;
+ }
+ if (replyType!="QStringList") {
+ msg = "Wrong reply type";
+ kdWarning()<<msg<<endl;
+ return;
+ }
+ QDataStream stream2(reply,IO_ReadOnly);
+ QStringList lt;
+ stream2>>lt;
+ if (lt.count()!=1) {
+ msg = "Wrong or missing log (may cancel pressed).";
+ kdDebug()<< msg << endl;
+ return;
+ }
+ msg = lt[0];
+ QValueList<svn::Path> targets;
+ for (unsigned j=0; j<url.count();++j) {
+ targets.push_back(svn::Path(url[j].path()));
+ }
+ svn::Revision nnum=svn::Revision::UNDEFINED;
+ try {
+ nnum = m_pData->m_Svnclient->commit(svn::Targets(targets),msg,svn::DepthInfinity,false);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ }
+ for (unsigned j=0;j<url.count();++j) {
+ QString userstring;
+ if (nnum!=svn::Revision::UNDEFINED) {
+ userstring = i18n( "Committed revision %1." ).arg(nnum.toString());
+ } else {
+ userstring = i18n ( "Nothing to commit." );
+ }
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "path", url[j].path() );
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "action", "0" );
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "kind", "0" );
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "mime_t", "" );
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "content", "0" );
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "prop", "0" );
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "rev" , QString::number(nnum) );
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "string", userstring );
+ m_pData->m_Listener.incCounter();
+ }
+}
+
+void kio_svnProtocol::checkout(const KURL&src,const KURL&target,const int rev, const QString&revstring)
+{
+ svn::Revision where(rev,revstring);
+ svn::Revision peg = svn::Revision::UNDEFINED;
+ svn::Path _target(target.path());
+ try {
+ KURL _src = makeSvnUrl(src);
+ m_pData->m_Svnclient->checkout(_src.url(),_target,where,peg,svn::DepthInfinity,false,false);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ }
+}
+
+void kio_svnProtocol::svnlog(int revstart,const QString&revstringstart,int revend, const QString&revstringend, const KURL::List&urls)
+{
+ svn::Revision start(revstart,revstringstart);
+ svn::Revision end(revend,revstringend);
+ svn::LogEntriesPtr logs;
+
+ for (unsigned j = 0; j<urls.count();++j) {
+ logs = 0;
+ try {
+ logs = m_pData->m_Svnclient->log(makeSvnUrl(urls[j]),start,end,svn::Revision::UNDEFINED,true,true,0);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ break;
+ }
+ if (!logs) {
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify(10,'0')+"path",urls[j].path());
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify(10,'0')+"string",
+ i18n("Empty logs"));
+ m_pData->m_Listener.incCounter();
+ continue;
+ }
+ for (unsigned int i = 0; i < logs->count();++i) {
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "path",urls[j].path());
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "rev",
+ QString::number( (*logs)[i].revision));
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+"author",
+ (*logs)[i].author);
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+"logmessage",
+ (*logs)[i].message);
+ m_pData->m_Listener.incCounter();
+ for (unsigned z = 0; z<(*logs)[i].changedPaths.count();++z) {
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "rev",
+ QString::number( (*logs)[i].revision));
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "path",urls[j].path());
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "loggedpath",
+ (*logs)[i].changedPaths[z].path);
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "loggedaction",
+ QChar((*logs)[i].changedPaths[z].action));
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "loggedcopyfrompath",
+ (*logs)[i].changedPaths[z].copyFromPath);
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "loggedcopyfromrevision",
+ QString::number((*logs)[i].changedPaths[z].copyFromRevision));
+ m_pData->m_Listener.incCounter();
+ }
+ }
+ }
+}
+
+void kio_svnProtocol::revert(const KURL::List&l)
+{
+ QValueList<svn::Path> list;
+ for (unsigned j=0; j<l.count();++j) {
+ list.append(svn::Path(l[j].path()));
+ }
+ svn::Targets target(list);
+ try {
+ m_pData->m_Svnclient->revert(target,svn::DepthEmpty);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ }
+}
+
+void kio_svnProtocol::wc_switch(const KURL&wc,const KURL&target,bool rec,int rev,const QString&revstring)
+{
+ svn::Revision where(rev,revstring);
+ svn::Path wc_path(wc.path());
+ try {
+ m_pData->m_Svnclient->doSwitch(wc_path,makeSvnUrl(target.url()),where,rec?svn::DepthInfinity:svn::DepthFiles);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ }
+}
+
+void kio_svnProtocol::diff(const KURL&uri1,const KURL&uri2,int rnum1,const QString&rstring1,int rnum2, const QString&rstring2,bool rec)
+{
+ QByteArray ex;
+ /// @todo read settings for diff (ignore contentype)
+ try {
+ svn::Revision r1(rnum1,rstring1);
+ svn::Revision r2(rnum2,rstring2);
+ QString u1 = makeSvnUrl(uri1,true);
+ QString u2 = makeSvnUrl(uri2,true);
+ KTempDir tdir;
+ kdDebug() << "kio_ksvn::diff : " << u1 << " at revision " << r1.toString() << " with "
+ << u2 << " at revision " << r2.toString()
+ << endl ;
+
+ tdir.setAutoDelete(true);
+ ex = m_pData->m_Svnclient->diff(svn::Path(tdir.name()),
+ u1,u2,svn::Path(),r1, r2,rec?svn::DepthInfinity:svn::DepthEmpty,false,false,false);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ return;
+ }
+ QString out = QString::FROMUTF8(ex);
+ QTextIStream stream(&out);
+ while (!stream.atEnd()) {
+ setMetaData(QString::number(m_pData->m_Listener.counter()).rightJustify( 10,'0' )+ "diffresult",stream.readLine());
+ m_pData->m_Listener.incCounter();
+ }
+}
+
+void kio_svnProtocol::import(const KURL& repos, const KURL& wc)
+{
+ try {
+ QString target = makeSvnUrl(repos);
+ QString path = wc.path();
+ m_pData->m_Svnclient->import(svn::Path(path),target,QString::null,svn::DepthInfinity,false,false);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ return;
+ }
+ finished();
+}
+
+void kio_svnProtocol::add(const KURL& wc)
+{
+ QString path = wc.path();
+ try {
+ /* rec */
+ m_pData->m_Svnclient->add(svn::Path(path),svn::DepthInfinity);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ return;
+ }
+ finished();
+}
+
+void kio_svnProtocol::wc_delete(const KURL::List&l)
+{
+ svn::Pathes p;
+ for ( QValueListConstIterator<KURL> it = l.begin(); it != l.end() ; ++it ) {
+ p.append((*it).path());
+ }
+ try {
+ m_pData->m_Svnclient->remove(svn::Targets(p),false);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ return;
+ }
+ finished();
+}
+
+void kio_svnProtocol::wc_resolve(const KURL&url,bool recurse)
+{
+ try {
+ svn::Depth depth=recurse?svn::DepthInfinity:svn::DepthEmpty;
+ m_pData->m_Svnclient->resolve(url.path(),depth);
+ } catch (const svn::ClientException&e) {
+ error(KIO::ERR_SLAVE_DEFINED,e.msg());
+ return;
+ }
+ finished();
+}
+
+void kio_svnProtocol::streamWritten(const KIO::filesize_t current)
+{
+ processedSize(current);
+}
+
+void kio_svnProtocol::streamSendMime(KMimeMagicResult* mt)
+{
+ if (mt) {
+ mimeType(mt->mimeType());
+ }
+}
+
+void kio_svnProtocol::streamPushData(QByteArray array)
+{
+ data(array);
+}
+
+void kio_svnProtocol::contextProgress(long long int current, long long int)
+{
+ if (m_pData->dispProgress) {
+ processedSize(current);
+ }
+}
+
+void kio_svnProtocol::streamTotalSizeNull()
+{
+ totalSize(0);
+}
+
+
+/*!
+ \fn kio_svnProtocol::getDefaultLog()
+ */
+QString kio_svnProtocol::getDefaultLog()
+{
+ QString res = QString::null;
+ Kdesvnsettings::self()->readConfig();
+ if (Kdesvnsettings::kio_use_standard_logmsg()) {
+ res = Kdesvnsettings::kio_standard_logmsg();
+ }
+ return res;
+}
+
+} // namespace KIO
diff --git a/src/kiosvn/kiosvn.h b/src/kiosvn/kiosvn.h
new file mode 100644
index 0000000..a3383e1
--- /dev/null
+++ b/src/kiosvn/kiosvn.h
@@ -0,0 +1,120 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * 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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef KIOSVN_H
+#define KIOSVN_H
+
+#include "kiobytestream.h"
+
+#include <qstring.h>
+#include <qcstring.h>
+#include <kurl.h>
+
+#include <kio/global.h>
+#include <kio/slavebase.h>
+
+
+#include <sys/stat.h>
+#include <qvaluelist.h>
+
+namespace KIO
+{
+
+class KioSvnData;
+
+/**
+@author Rajko Albrecht
+*/
+class kio_svnProtocol : public KIO::SlaveBase,public StreamWrittenCb
+{
+public:
+ kio_svnProtocol(const QCString &pool_socket, const QCString &app_socket);
+ virtual ~kio_svnProtocol();
+ virtual void listDir (const KURL&url);
+ virtual void stat(const KURL& url);
+ virtual void get(const KURL& url);
+ virtual void mkdir (const KURL &url, int permissions);
+ virtual void mkdir (const KURL::List &urls, int permissions);
+ virtual void rename(const KURL&src,const KURL&target,bool force);
+ virtual void del(const KURL&url,bool isfile);
+ virtual void copy(const KURL&src,const KURL&dest,int permissions,bool overwrite);
+ virtual void checkout(const KURL&src,const KURL&target,const int rev, const QString&revstring);
+ virtual void svnlog(int,const QString&,int, const QString&, const KURL::List&);
+ virtual void revert(const KURL::List&);
+ virtual void wc_switch(const KURL&,const KURL&,bool,int,const QString&);
+ virtual void diff(const KURL&,const KURL&,int,const QString&,int, const QString&,bool);
+ virtual void import( const KURL& repos, const KURL& wc);
+ virtual void add(const KURL& wc);
+ virtual void wc_delete(const KURL::List&);
+ virtual void special(const QByteArray& data);
+ virtual void wc_resolve(const KURL&,bool);
+ /* looked on kio::svn from kdesdk */
+ enum KSVN_METHOD {
+ /* KURL repository, KURL target, int revnumber, QString revkind */
+ SVN_CHECKOUT = 1,
+ /* KURL wc, int revnumber, QString revkind */
+ /* refkind may empty or HEAD or START, will get parsed if revnumber is -1 */
+ SVN_UPDATE = 2,
+ /* KURL::List */
+ SVN_COMMIT = 3,
+ /* int revstart, QString revstartstring, int revend, QString revendstring, KURL::List */
+ SVN_LOG=4,
+ SVN_IMPORT=5,
+ /* KURL */
+ SVN_ADD=6,
+ /*KURL::List */
+ SVN_DEL=7,
+ /* KURL::List */
+ SVN_REVERT=8,
+ /* KURL wc,bool checkRepos, bool recurse */
+ SVN_STATUS=9,
+ /* KURL::List */
+ SVN_MKDIR=10,
+ /* KURL, bool */
+ SVN_RESOLVE=11,
+ /* KURL working copy, KURL new_repository_url, bool recurse, int rev, QString revstring */
+ SVN_SWITCH=12,
+ /* KURL uri1, KURL uri2, int r1, QString rstring1, int r2, QString rstring 2, bool recursive */
+ SVN_DIFF=13
+ };
+
+ void contextProgress(long long int current, long long int max);
+ virtual void streamWritten(const KIO::filesize_t current);
+ virtual void streamPushData(QByteArray);
+ virtual void streamSendMime(KMimeMagicResult*mt);
+ virtual void streamTotalSizeNull();
+
+protected:
+ virtual void commit(const KURL::List&);
+ virtual void status(const KURL&,bool,bool);
+ virtual void update(const KURL&,int,const QString&);
+
+private:
+ KioSvnData*m_pData;
+ bool createUDSEntry( const QString& filename, const QString& user, long long int size, bool isdir, time_t mtime, KIO::UDSEntry& entry);
+ QString makeSvnUrl(const KURL&url,bool check_wc=true);
+ bool checkWc(const KURL&url);
+ bool getLogMsg(QString&);
+protected:
+ QString getDefaultLog();
+};
+
+}
+
+#endif
diff --git a/src/kiosvn/ksvn+file.protocol b/src/kiosvn/ksvn+file.protocol
new file mode 100644
index 0000000..27edbef
--- /dev/null
+++ b/src/kiosvn/ksvn+file.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=ksvn+file
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet
diff --git a/src/kiosvn/ksvn+http.protocol b/src/kiosvn/ksvn+http.protocol
new file mode 100644
index 0000000..e16c353
--- /dev/null
+++ b/src/kiosvn/ksvn+http.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=ksvn+http
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet
diff --git a/src/kiosvn/ksvn+https.protocol b/src/kiosvn/ksvn+https.protocol
new file mode 100644
index 0000000..fa828eb
--- /dev/null
+++ b/src/kiosvn/ksvn+https.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=ksvn+https
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet
diff --git a/src/kiosvn/ksvn+ssh.protocol b/src/kiosvn/ksvn+ssh.protocol
new file mode 100644
index 0000000..891abc9
--- /dev/null
+++ b/src/kiosvn/ksvn+ssh.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=ksvn+ssh
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet
diff --git a/src/kiosvn/ksvn.protocol b/src/kiosvn/ksvn.protocol
new file mode 100644
index 0000000..7b2cc54
--- /dev/null
+++ b/src/kiosvn/ksvn.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=ksvn
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet
diff --git a/src/kiosvn/svn+file.protocol b/src/kiosvn/svn+file.protocol
new file mode 100644
index 0000000..9b0a4fd
--- /dev/null
+++ b/src/kiosvn/svn+file.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=svn+file
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet
diff --git a/src/kiosvn/svn+http.protocol b/src/kiosvn/svn+http.protocol
new file mode 100644
index 0000000..6be6943
--- /dev/null
+++ b/src/kiosvn/svn+http.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=svn+http
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet
diff --git a/src/kiosvn/svn+https.protocol b/src/kiosvn/svn+https.protocol
new file mode 100644
index 0000000..fc23bdc
--- /dev/null
+++ b/src/kiosvn/svn+https.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=svn+https
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet
diff --git a/src/kiosvn/svn+ssh.protocol b/src/kiosvn/svn+ssh.protocol
new file mode 100644
index 0000000..1c261b8
--- /dev/null
+++ b/src/kiosvn/svn+ssh.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=svn+ssh
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet
diff --git a/src/kiosvn/svn.protocol b/src/kiosvn/svn.protocol
new file mode 100644
index 0000000..02226f2
--- /dev/null
+++ b/src/kiosvn/svn.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_ksvn
+protocol=svn
+input=none
+output=filesystem
+reading=true
+writing=true
+deleting=true
+makedir=true
+linking=false
+moving=true
+deleteRecursive=true
+listing=Name,Size,Date,Owner
+defaultMimetype=application/octet-stream
+Icon=remote
+Description=Subversion ioslave
+Description[br]=Sklav E/D Subversion
+Description[ca]=Ioslave de Subversion
+Description[cs]=Subversion protokol
+Description[de]=Ein-/Ausgabemodul für Subversion
+Description[es]=El ioslave de Subversion
+Description[et]=Subversioni IO-moodul
+Description[fr]=ioslave subversion
+Description[ga]=ioslave Subversion
+Description[hu]=Subversion KDE-protokoll
+Description[it]=Slave I/O di Subversion
+Description[pl]=Wtyczka protokołu Subversion
+Description[pt]='Ioslave' para Subversion
+Description[pt_BR]=ioslave de Subversão
+Description[ru]=Доступ к хранилищу Subversion
+Description[sl]=ioslave za Subversion
+Description[sr]=IOSlave за Subversion
+Description[sr@Latn]=IOSlave za Subversion
+Description[sv]=Subversion I/O-slav
+Description[tr]=Alt Version ioslave
+Description[uk]=Підлеглий В/В Subversion
+Description[xx]=xxSubversion ioslavexx
+maxInstances=5
+class=:internet