summaryrefslogtreecommitdiffstats
path: root/vcs/subversion
diff options
context:
space:
mode:
Diffstat (limited to 'vcs/subversion')
-rw-r--r--vcs/subversion/Makefile.am38
-rw-r--r--vcs/subversion/README.dox13
-rw-r--r--vcs/subversion/commitdlg.cpp47
-rw-r--r--vcs/subversion/commitdlg.h37
-rw-r--r--vcs/subversion/commitdlgbase.ui111
-rw-r--r--vcs/subversion/configure.in.bot9
-rw-r--r--vcs/subversion/configure.in.in134
-rw-r--r--vcs/subversion/integrator/Makefile.am14
-rw-r--r--vcs/subversion/integrator/kdevsubversionintegrator.desktop45
-rw-r--r--vcs/subversion/integrator/subversionintegrator.cpp54
-rw-r--r--vcs/subversion/integrator/subversionintegrator.h39
-rw-r--r--vcs/subversion/integrator/svnintegratordlg.cpp122
-rw-r--r--vcs/subversion/integrator/svnintegratordlg.h39
-rw-r--r--vcs/subversion/integrator/svnintegratordlgbase.ui190
-rw-r--r--vcs/subversion/kdevpart_subversion.rc31
-rw-r--r--vcs/subversion/kdevsubversion.desktop34
-rw-r--r--vcs/subversion/kdevsvn+file.protocol39
-rw-r--r--vcs/subversion/kdevsvn+http.protocol39
-rw-r--r--vcs/subversion/kdevsvn+https.protocol39
-rw-r--r--vcs/subversion/kdevsvn+ssh.protocol39
-rw-r--r--vcs/subversion/kdevsvn+svn.protocol39
-rw-r--r--vcs/subversion/kdevsvnd.cpp394
-rw-r--r--vcs/subversion/kdevsvnd.desktop31
-rw-r--r--vcs/subversion/kdevsvnd.h50
-rw-r--r--vcs/subversion/kdevsvnd_widgets.cpp70
-rw-r--r--vcs/subversion/kdevsvnd_widgets.h41
-rw-r--r--vcs/subversion/subversion_core.cpp738
-rw-r--r--vcs/subversion/subversion_core.h105
-rw-r--r--vcs/subversion/subversion_fileinfo.cpp507
-rw-r--r--vcs/subversion/subversion_fileinfo.h73
-rw-r--r--vcs/subversion/subversion_global.h56
-rw-r--r--vcs/subversion/subversion_part.cpp569
-rw-r--r--vcs/subversion/subversion_part.h119
-rw-r--r--vcs/subversion/subversion_widget.cpp136
-rw-r--r--vcs/subversion/subversion_widget.h95
-rw-r--r--vcs/subversion/subversiondiff.ui100
-rw-r--r--vcs/subversion/subversionprojectwidget.ui89
-rw-r--r--vcs/subversion/svn_blamewidget.cpp135
-rw-r--r--vcs/subversion/svn_blamewidget.h77
-rw-r--r--vcs/subversion/svn_co.ui335
-rw-r--r--vcs/subversion/svn_commitdlgbase.ui131
-rw-r--r--vcs/subversion/svn_copydlgwidget.ui238
-rw-r--r--vcs/subversion/svn_copywidget.cpp75
-rw-r--r--vcs/subversion/svn_copywidget.h32
-rw-r--r--vcs/subversion/svn_fileselectdlg_commit.cpp163
-rw-r--r--vcs/subversion/svn_fileselectdlg_commit.h52
-rw-r--r--vcs/subversion/svn_kio.cpp2155
-rw-r--r--vcs/subversion/svn_kio.h163
-rw-r--r--vcs/subversion/svn_logviewoptiondlgbase.ui156
-rw-r--r--vcs/subversion/svn_logviewwidget.cpp273
-rw-r--r--vcs/subversion/svn_logviewwidget.h93
-rw-r--r--vcs/subversion/svn_mergeoptiondlgbase.ui374
-rw-r--r--vcs/subversion/svn_mergewidget.cpp99
-rw-r--r--vcs/subversion/svn_mergewidget.h50
-rw-r--r--vcs/subversion/svn_switchdlgbase.ui213
-rw-r--r--vcs/subversion/svn_switchwidget.cpp60
-rw-r--r--vcs/subversion/svn_switchwidget.h31
-rw-r--r--vcs/subversion/svnssltrustpromptbase.ui116
58 files changed, 9346 insertions, 0 deletions
diff --git a/vcs/subversion/Makefile.am b/vcs/subversion/Makefile.am
new file mode 100644
index 00000000..449d3889
--- /dev/null
+++ b/vcs/subversion/Makefile.am
@@ -0,0 +1,38 @@
+INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/interfaces/extensions $(SVN_INCLUDE) $(all_includes)
+
+METASOURCES = AUTO
+
+kde_module_LTLIBRARIES = libkdevsubversion.la kio_kdevsvn.la kded_kdevsvnd.la
+
+libkdevsubversion_la_SOURCES = subversion_core.cpp subversion_fileinfo.cpp \
+ subversion_fileinfo.skel subversion_part.cpp subversion_widget.cpp subversiondiff.ui \
+ subversionprojectwidget.ui svn_blamewidget.cpp svn_co.ui svn_commitdlgbase.ui svn_copydlgwidget.ui \
+ svn_copywidget.cpp svn_fileselectdlg_commit.cpp svn_logviewoptiondlgbase.ui \
+ svn_logviewwidget.cpp svn_mergeoptiondlgbase.ui svn_mergewidget.cpp svn_switchdlgbase.ui \
+ svn_switchwidget.cpp
+libkdevsubversion_la_LIBADD = $(top_builddir)/lib/libkdevelop.la $(top_builddir)/lib/interfaces/extensions/libkdevextensions.la
+libkdevsubversion_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN)
+
+
+kio_kdevsvn_la_SOURCES = svn_kio.cpp
+kio_kdevsvn_la_LIBADD = $(LIB_KIO)
+kio_kdevsvn_la_LDFLAGS = -module $(all_libraries) $(KDE_PLUGIN) $(SVN_LIB)
+
+kded_kdevsvnd_la_SOURCES = commitdlg.cpp commitdlgbase.ui kdevsvnd.cpp \
+ kdevsvnd.skel kdevsvnd_widgets.cpp svnssltrustpromptbase.ui
+kded_kdevsvnd_la_LIBADD = $(LIB_KIO) -lkdeinit_kded
+kded_kdevsvnd_la_LDFLAGS = -module $(all_libraries) $(KDE_PLUGIN)
+
+kdeddir = $(kde_servicesdir)/kded
+kded_DATA = kdevsvnd.desktop
+
+servicedir = $(kde_servicesdir)
+service_DATA = kdevsubversion.desktop
+
+protocoldir = $(kde_servicesdir)
+protocol_DATA = kdevsvn+file.protocol kdevsvn+http.protocol kdevsvn+https.protocol kdevsvn+ssh.protocol kdevsvn+svn.protocol
+
+
+SUBDIRS = integrator
+noinst_HEADERS = commitdlg.h kdevsvnd.h svn_blamewidget.h svn_copywidget.h \
+ svn_fileselectdlg_commit.h svn_logviewwidget.h svn_mergewidget.h svn_switchwidget.h
diff --git a/vcs/subversion/README.dox b/vcs/subversion/README.dox
new file mode 100644
index 00000000..df3badcc
--- /dev/null
+++ b/vcs/subversion/README.dox
@@ -0,0 +1,13 @@
+/** \class subversionPart
+Integrates the SVN (Subversion) version management system into KDevelop.
+
+\authors <a href="mailto:marchand AT kde.org">Mickael Marchand</a>
+
+\maintainer <a href="mailto:marchand AT kde.org">Mickael Marchand</a>
+
+\feature Integrates the SVN (Subversion) version management system into KDevelop.
+
+\requirement You need to compile and install kdesdk/kioslave/svn
+
+*/
+
diff --git a/vcs/subversion/commitdlg.cpp b/vcs/subversion/commitdlg.cpp
new file mode 100644
index 00000000..e227dd67
--- /dev/null
+++ b/vcs/subversion/commitdlg.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * This file is part of KDevelop *
+ * Copyright (C) 2007 The KDevelop Authors <kdevelop-devel@kdevelop.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library 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 "commitdlg.h"
+#include <qevent.h>
+#include <ktextedit.h>
+
+CommitDlg::CommitDlg( QWidget* parent )
+ : CommitDlgBase( parent )
+{
+ textMessage->installEventFilter(this);
+}
+
+bool CommitDlg::eventFilter( QObject* obj, QEvent* ev )
+{
+ if( ev->type() == QEvent::KeyPress )
+ {
+ QKeyEvent* k = static_cast<QKeyEvent*>(ev);
+ if( ( k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter ) && k->state() == Qt::ControlButton )
+ {
+ accept();
+ return true;
+ }
+ }
+ return false;
+}
+
+#include "commitdlg.moc"
+
+//kate: space-indent on; indent-width 4; replace-tabs on; auto-insert-doxygen on; indent-mode cstyle;
diff --git a/vcs/subversion/commitdlg.h b/vcs/subversion/commitdlg.h
new file mode 100644
index 00000000..4ac54054
--- /dev/null
+++ b/vcs/subversion/commitdlg.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * This file is part of KDevelop *
+ * Copyright (C) 2007 The KDevelop Authors <kdevelop-devel@kdevelop.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library 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 COMMITDLG_H
+#define COMMITDLG_H
+
+#include "commitdlgbase.h"
+
+class CommitDlg : public CommitDlgBase
+{
+ Q_OBJECT
+public:
+ CommitDlg( QWidget* = 0 );
+protected:
+ bool eventFilter( QObject* o, QEvent* e );
+};
+
+#endif
+
+//kate: space-indent on; indent-width 4; replace-tabs on; auto-insert-doxygen on; indent-mode cstyle;
diff --git a/vcs/subversion/commitdlgbase.ui b/vcs/subversion/commitdlgbase.ui
new file mode 100644
index 00000000..76499a60
--- /dev/null
+++ b/vcs/subversion/commitdlgbase.ui
@@ -0,0 +1,111 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>CommitDlgBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>CommitDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>451</width>
+ <height>337</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Log Message</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KTextEdit">
+ <property name="name">
+ <cstring>textMessage</cstring>
+ </property>
+ </widget>
+ <widget class="KTextEdit">
+ <property name="name">
+ <cstring>listMessage</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>220</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pushButton1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pushButton2</cstring>
+ </property>
+ <property name="text">
+ <string>Ca&amp;ncel</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>pushButton1</sender>
+ <signal>clicked()</signal>
+ <receiver>CommitDlgBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>pushButton2</sender>
+ <signal>clicked()</signal>
+ <receiver>CommitDlgBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>ktextedit.h</includehint>
+ <includehint>ktextedit.h</includehint>
+</includehints>
+</UI>
diff --git a/vcs/subversion/configure.in.bot b/vcs/subversion/configure.in.bot
new file mode 100644
index 00000000..ccab94db
--- /dev/null
+++ b/vcs/subversion/configure.in.bot
@@ -0,0 +1,9 @@
+if test "x$with_subversion" = xcheck && test -z "$SVN_SUBDIR"; then
+ echo ""
+ echo "You're missing Subversion libraries (1.x)"
+ echo "KDE will not be able to browse Subversion repositories without it,"
+ echo "consider installing it."
+ echo "Look at kioslave/svn/README for more information"
+ echo ""
+ all_tests=bad
+fi
diff --git a/vcs/subversion/configure.in.in b/vcs/subversion/configure.in.in
new file mode 100644
index 00000000..9bccba66
--- /dev/null
+++ b/vcs/subversion/configure.in.in
@@ -0,0 +1,134 @@
+SVN_SUBDIR=""
+
+AC_ARG_ENABLE(subversion, AC_HELP_STRING([--disable-subversion], [disable vcs support for subversion]), [with_subversion=${enableval}], [with_subversion=check])
+
+
+
+if test "x$with_subversion" != xno; then
+
+ APR_CONFIGS="/usr/bin/apr-config /usr/bin/apr-1-config /usr/local/bin/apr-config /usr/local/apr/bin/apr-config"
+ SVN_SUBDIR="svn"
+ AC_ARG_WITH(apr-config,
+ [[ --with-apr-config=FILE Use the given path to apr-config when determining
+ APR configuration; defaults to "apr-config"]],
+ [
+ if test "$withval" != "yes" -a "$withval" != ""; then
+ APR_CONFIGS=$withval
+ fi
+ ])
+ AC_MSG_CHECKING([for APR])
+ APR_CONFIG=""
+ for VALUE in $APR_CONFIGS ; do
+ if test -x "$VALUE"; then
+ if $VALUE --cflags > /dev/null; then
+ APR_CONFIG="$VALUE"
+ break
+ fi
+ fi
+ done
+ if test -n "$APR_CONFIG" ; then
+ AC_MSG_RESULT([$APR_CONFIG])
+ APR_CPPFLAGS="`$APR_CONFIG --cppflags`"
+ APR_INCLUDE="`$APR_CONFIG --includes`"
+ APR_LIBS="`$APR_CONFIG --link-ld --libs`"
+ else
+ AC_MSG_RESULT([not found])
+ SVN_SUBDIR=
+ fi
+
+ dnl
+ dnl APR util
+ dnl
+
+ APU_CONFIGS="/usr/bin/apu-config /usr/bin/apu-1-config /usr/local/bin/apu-config /usr/local/apu/bin/apu-config"
+ AC_ARG_WITH(apu-config,
+ [[ --with-apu-config=FILE Use the given path to apu-config when determining
+ APR util configuration; defaults to "apu-config"]],
+ [
+ if test "$withval" != "yes" -a "$withval" != ""; then
+ APU_CONFIGS=$withval
+ fi
+ ])
+ AC_MSG_CHECKING([for APR util])
+ APU_CONFIG=""
+ for VALUE in $APU_CONFIGS ; do
+ if test -x $VALUE
+ then
+ if $VALUE --includes > /dev/null; then
+ APU_CONFIG=$VALUE
+ break
+ fi
+ fi
+ done
+ if test -n "$APU_CONFIG"; then
+ AC_MSG_RESULT([found])
+ APR_INCLUDE="$APR_INCLUDE `$APU_CONFIG --includes`"
+ APR_LIBS="$APR_LIBS `$APU_CONFIG --link-ld --libs`"
+ else
+ AC_MSG_RESULT([not found])
+ SVN_SUBDIR=
+ fi
+
+ dnl Search for subversion libraries
+ dnl svn-config was removed at current subversion release.
+
+
+ SVN_INCLUDES="/usr/local/include /usr/include /usr/include/subversion-1 /usr/local/include/subversion-1"
+ AC_ARG_WITH(svn-include,
+ [[ --with-svn-include=DIR Use the given path to the subversion headers.]],
+ [
+ if test "$withval" != "yes" -a "$withval" != ""; then
+ SVN_INCLUDES=$withval
+ fi
+ ])
+ AC_MSG_CHECKING([for Subversion headers])
+ SVN_INCLUDE=""
+ for VALUE in $SVN_INCLUDES ; do
+ if test -f $VALUE/svn_types.h ; then
+ SVN_INCLUDE="-I$VALUE"
+ break
+ fi
+ done
+ if test $SVN_INCLUDE ; then
+ AC_MSG_RESULT([found])
+ else
+ AC_MSG_RESULT([not found])
+ SVN_SUBDIR=
+ fi
+ SVN_LIBS="/usr/local/lib /usr/lib /usr/lib64"
+ AC_ARG_WITH(svn-lib,
+ [[ --with-svn-lib=DIR Use the given path to the subversion libraries.]],
+ [
+ if test "$withval" != "yes" -a "$withval" != ""; then
+ SVN_LIBS=$withval
+ fi
+ ])
+ AC_MSG_CHECKING([for Subversion libraries])
+ SVN_LIB=""
+ for VALUE in $SVN_LIBS ; do
+ if ls $VALUE/libsvn_client-1.* 1>/dev/null 2>&1; then
+ SVN_LIB="-L$VALUE"
+ break
+ fi
+ done
+ if test $SVN_LIB ; then
+ AC_MSG_RESULT([found])
+ else
+ AC_MSG_RESULT([not found])
+ SVN_SUBDIR=
+ fi
+ SVN_LIB="$SVN_LIB $APR_LIBS -lsvn_client-1 -lsvn_subr-1 -lsvn_ra-1"
+ SVN_INCLUDE="$SVN_INCLUDE $APR_INCLUDE"
+ SVN_CPPFLAGS="$APR_CPPFLAGS $SVN_CPPFLAGS"
+
+ if test "x$with_subversion" != xcheck && test -z "$SVN_SUBDIR"; then
+ AC_MSG_ERROR([--enable-subversion was given, but test for subversion failed. Please install subversion headers and libraries and its dependencies (APR and APU utils)])
+ fi
+fi
+
+AM_CONDITIONAL(include_subversion, test -n "$SVN_SUBDIR")
+
+AC_SUBST(SVN_INCLUDE)
+AC_SUBST(SVN_LIB)
+AC_SUBST(SVN_CPPFLAGS)
+AM_CONDITIONAL(include_kioslave_svn, test -n "$SVN_SUBDIR")
diff --git a/vcs/subversion/integrator/Makefile.am b/vcs/subversion/integrator/Makefile.am
new file mode 100644
index 00000000..a0fe82cd
--- /dev/null
+++ b/vcs/subversion/integrator/Makefile.am
@@ -0,0 +1,14 @@
+INCLUDES = -I$(top_srcdir)/lib/interfaces \
+ -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/extras -I$(top_srcdir)/lib/util \
+ $(all_includes)
+METASOURCES = AUTO
+
+kde_module_LTLIBRARIES = libsubversionintegrator.la
+libsubversionintegrator_la_LDFLAGS = -avoid-version -no-undefined $(all_libraries)
+libsubversionintegrator_la_LIBADD =\
+ $(top_builddir)/lib/interfaces/extras/libkdevextras.la\
+ $(top_builddir)/lib/libkdevelop.la
+kde_services_DATA = kdevsubversionintegrator.desktop
+noinst_HEADERS = subversionintegrator.h svnintegratordlg.h
+libsubversionintegrator_la_SOURCES = subversionintegrator.cpp \
+ svnintegratordlgbase.ui svnintegratordlg.cpp
diff --git a/vcs/subversion/integrator/kdevsubversionintegrator.desktop b/vcs/subversion/integrator/kdevsubversionintegrator.desktop
new file mode 100644
index 00000000..4b3a1c1c
--- /dev/null
+++ b/vcs/subversion/integrator/kdevsubversionintegrator.desktop
@@ -0,0 +1,45 @@
+[Desktop Entry]
+Type=Service
+Name=KDevSubversionIntegrator
+Name[da]=KDevelop Subversion-integration
+Name[nds]=KDevelop-Subversion-Integreren
+Name[sk]=KDev Subversion integrácia
+Name[sv]=KDevelop Subversion-integration
+Name[zh_TW]=KDevelop Subversion 整合器
+Comment=Subversion Project Integration Facility
+Comment[ca]=Facilitat per a la integració amb Subversion
+Comment[da]=Subversion projektintegration
+Comment[de]=Subversion-Projektintegration
+Comment[el]=Λειτουργία ενσωμάτωσης Subversion στο έργο
+Comment[es]=Facilidad para integración con proyectos que utilicen Subversion
+Comment[et]=Subversion projekti põimimisvahend
+Comment[eu]=Subversion proiektuen integrazio-tesna
+Comment[fa]=تسهیلات مجتمع‌سازی پروژۀ زیرنسخه
+Comment[fr]=Fonction d'intégration pour un projet utilisant Subversion
+Comment[gl]=Utilidade para a integración de proxectos Subversión
+Comment[hu]=Projektintegrálást tesz lehetővé a Subversion-nel
+Comment[it]=Funzione di integrazione del progetto Subversion
+Comment[ja]=Subversion プロジェクト統合ツール
+Comment[ms]=Kemudahan Integrasi Projek Subversion
+Comment[nds]=Subversion-Projektintegreren
+Comment[ne]=सबभर्सन परियोजना एकिकरण सुविधा
+Comment[nl]=Subversion project-integratie
+Comment[pl]=Integracja z Subversion
+Comment[pt]=Integração com Projectos Subversion
+Comment[pt_BR]=Facilidade de Integração ao Projeto de Subversão
+Comment[ru]=Интеграция Subversion
+Comment[sk]=Subversion projektová integrácia
+Comment[sr]=Интеграција Subversion-а у пројекат
+Comment[sr@Latn]=Integracija Subversion-a u projekat
+Comment[sv]=Funktion för integrering av Subversion i projekt
+Comment[tr]=Subversion Proje Bütünleştirme Aracı
+Comment[zh_CN]=Subversion 工程集成功能
+Comment[zh_TW]=Subversion 專案整合工具
+Icon=misc
+Exec=blubb
+ServiceTypes=KDevelop/VCSIntegrator
+X-KDE-Library=libsubversionintegrator
+X-KDevelop-Default=false
+X-KDevelop-VCS=Subversion
+X-KDevelop-VCSPlugin=kdevsubversion
+X-KDevelop-Version=5
diff --git a/vcs/subversion/integrator/subversionintegrator.cpp b/vcs/subversion/integrator/subversionintegrator.cpp
new file mode 100644
index 00000000..65bf1a78
--- /dev/null
+++ b/vcs/subversion/integrator/subversionintegrator.cpp
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "subversionintegrator.h"
+
+#include <kdevgenericfactory.h>
+#include <kdevplugininfo.h>
+
+#include "svnintegratordlg.h"
+
+static const KDevPluginInfo data("kdevsubversionintegrator");
+typedef KDevGenericFactory<SubversionIntegrator> SubversionIntegratorFactory;
+K_EXPORT_COMPONENT_FACTORY( libsubversionintegrator, SubversionIntegratorFactory(data) )
+
+SubversionIntegrator::SubversionIntegrator(QObject* parent, const char* name,
+ const QStringList // args
+ )
+ :KDevVCSIntegrator(parent, name)
+{
+}
+
+SubversionIntegrator::~SubversionIntegrator()
+{
+}
+
+VCSDialog* SubversionIntegrator::fetcher(QWidget* // parent
+ )
+{
+ return 0;
+}
+
+VCSDialog* SubversionIntegrator::integrator(QWidget* parent)
+{
+ SvnIntegratorDlg *dlg = new SvnIntegratorDlg(parent);
+ return dlg;
+}
+
+#include "subversionintegrator.moc"
diff --git a/vcs/subversion/integrator/subversionintegrator.h b/vcs/subversion/integrator/subversionintegrator.h
new file mode 100644
index 00000000..e58c7786
--- /dev/null
+++ b/vcs/subversion/integrator/subversionintegrator.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef SUBVERSIONINTEGRATOR_H
+#define SUBVERSIONINTEGRATOR_H
+
+#include <kdevvcsintegrator.h>
+
+#include <qstringlist.h>
+
+class SubversionIntegrator : public KDevVCSIntegrator
+{
+Q_OBJECT
+public:
+ SubversionIntegrator(QObject* parent, const char* name, const QStringList args = QStringList());
+ ~SubversionIntegrator();
+
+ virtual VCSDialog* fetcher(QWidget* parent);
+ virtual VCSDialog* integrator(QWidget* parent);
+
+};
+
+#endif
diff --git a/vcs/subversion/integrator/svnintegratordlg.cpp b/vcs/subversion/integrator/svnintegratordlg.cpp
new file mode 100644
index 00000000..9d271a90
--- /dev/null
+++ b/vcs/subversion/integrator/svnintegratordlg.cpp
@@ -0,0 +1,122 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * Copyright (C) 2004 *
+ * 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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "svnintegratordlg.h"
+#include "blockingkprocess.h"
+#include <kurl.h>
+#include <kio/jobclasses.h>
+#include <kio/job.h>
+#include <kurlrequester.h>
+#include <kdebug.h>
+#include <qradiobutton.h>
+#include <kio/scheduler.h>
+#include <kprocess.h>
+#include <kdeversion.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <kio/netaccess.h>
+
+using namespace KIO;
+
+SvnIntegratorDlg::SvnIntegratorDlg( QWidget *parent, const char *name )
+ : SvnIntegratorDlgBase( parent, name )
+{
+ repos1->setMode( KFile::Directory );
+}
+
+void SvnIntegratorDlg::accept()
+{
+ // to let ioslave know which protocol it should start.
+ KURL protocolUrl = KURL("kdevsvn+svn://blah/");
+ KURL servURL( repos1->url() );
+ if ( servURL.isEmpty() ) return;
+
+ kdDebug( 9036 ) << "servURL : " << servURL.prettyURL() << endl;
+ if ( createProject->isChecked() )
+ {
+ KURL::List list;
+ list << servURL; // project root directory
+ KURL miscURL = servURL.url();
+ miscURL.setPath( servURL.path() + "/tags/" );
+ list << miscURL;
+ miscURL.setPath( servURL.path() + "/branches/" );
+ list << miscURL;
+ miscURL.setPath( servURL.path() + "/trunk/" );
+ list << miscURL;
+
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 10; // MKDIR(list)
+ s << cmd << list;
+ KIO::SimpleJob* job = KIO::special( protocolUrl, parms, true );
+ if( !NetAccess::synchronousRun( job, 0 ) ){
+ KMessageBox::error( this, i18n("Unable to create project directories on repository") );
+ return;
+ }
+
+ QByteArray parms2;
+ QDataStream s2( parms2, IO_WriteOnly );
+ cmd = 5; //IMPORT
+ servURL.setPath( servURL.path() + "/trunk/" );
+ s2 << cmd << servURL << KURL::fromPathOrURL( m_projectLocation );
+ KIO::SimpleJob* importJob = KIO::special( protocolUrl, parms2, true );
+ if( !NetAccess::synchronousRun( importJob, 0 ) ){
+ KMessageBox::error( this, i18n("Unable to import into repository.") );
+ return;
+ }
+ }
+ //delete the template directory and checkout a fresh one from the server
+ BlockingKProcess *rmproc = new BlockingKProcess();
+ *rmproc << "rm";
+ *rmproc << "-f" << "-r" << m_projectLocation;
+ rmproc->start();
+
+ delete rmproc;
+ rmproc = NULL;
+
+ QByteArray parms3;
+ QDataStream s3( parms3, IO_WriteOnly );
+ int cmd2 = 1; //CHECKOUT
+ int rev = -1;
+
+ s3 << cmd2 << servURL << KURL::fromPathOrURL( m_projectLocation ) << rev << QString( "HEAD" );
+ SimpleJob *job2 = KIO::special( protocolUrl, parms3, true );
+ if( ! NetAccess::synchronousRun( job2, 0 ) ){
+ // Checkout failed
+ KMessageBox::error(this, i18n("Unable to checkout from repository.") );
+ return;
+ }
+}
+
+void SvnIntegratorDlg::init( const QString &projectName, const QString &projectLocation )
+{
+ m_name = projectName;
+ m_projectLocation = projectLocation;
+}
+
+QWidget *SvnIntegratorDlg::self()
+{
+ return const_cast<SvnIntegratorDlg*>( this );
+}
+
+#include "svnintegratordlg.moc"
diff --git a/vcs/subversion/integrator/svnintegratordlg.h b/vcs/subversion/integrator/svnintegratordlg.h
new file mode 100644
index 00000000..c68ee256
--- /dev/null
+++ b/vcs/subversion/integrator/svnintegratordlg.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.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; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef SVNINTEGRATORDLG_H
+#define SVNINTEGRATORDLG_H
+
+#include "svnintegratordlgbase.h"
+#include <kdevvcsintegrator.h>
+
+class SvnIntegratorDlg: public SvnIntegratorDlgBase, public VCSDialog {
+Q_OBJECT
+public:
+ SvnIntegratorDlg(QWidget *parent = 0, const char *name = 0);
+
+ virtual void accept();
+ virtual void init(const QString &projectName, const QString &projectLocation);
+ virtual QWidget *self();
+private:
+ QString m_name;
+ QString m_projectLocation;
+};
+
+#endif
diff --git a/vcs/subversion/integrator/svnintegratordlgbase.ui b/vcs/subversion/integrator/svnintegratordlgbase.ui
new file mode 100644
index 00000000..a2ec9982
--- /dev/null
+++ b/vcs/subversion/integrator/svnintegratordlgbase.ui
@@ -0,0 +1,190 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SvnIntegratorDlgBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>SvnIntegratorDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>648</width>
+ <height>429</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QButtonGroup" row="0" column="0">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="title">
+ <string></string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>doNothing</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Do not do anything</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Adds subversion menus to project.
+
+NOTE: Unless you import the project
+out of kdevelop, you will not be able
+to perform any subversion operations.</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Adds subversion menus to project.
+
+NOTE: Unless you import the project
+out of kdevelop, you will not be able
+to perform any subversion operations.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>createProject</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Create a project tree and import new project into trunk, then checkout from the repository</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Creates project, imports it into the subversion
+repository and checks it out as a working copy.
+
+NOTE: The repository has to exist.
+e.g. has been created with 'svnadmin'</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Creates project, imports it into the subversion
+repository and checks it out as a working copy.
+
+NOTE: The repository has to exist.
+e.g. has been created with 'svnadmin'</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Example for the url (if /home/user/subversion is the subversion repository):
+file:///home/user/subversion/mynewproject</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>repositoryLabel1</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Repository:</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>repos1</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Subversion repository location.
+The repository has to exist -
+e.g. has been created with 'svnadmin'</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Subversion repository location. This should include the subdirectory for the project in the repository. The project subdirectory and further subdirectories will be created.
+
+So for example if you give http://localhost/svn/projectname the following directories will be created and the project imported into the trunk subdirectory:
+http://localhost/svn/projectname
+http://localhost/svn/projectname/tags
+http://localhost/svn/projectname/branches
+http://localhost/svn/projectname/trunk</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>131</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>createProject</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>repositoryLabel1</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>createProject</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>repos1</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/vcs/subversion/kdevpart_subversion.rc b/vcs/subversion/kdevpart_subversion.rc
new file mode 100644
index 00000000..ad957e99
--- /dev/null
+++ b/vcs/subversion/kdevpart_subversion.rc
@@ -0,0 +1,31 @@
+<!DOCTYPE kpartgui>
+<kpartplugin name="subversion" library="libsubversionplugin" version="2">
+<MenuBar>
+ <Menu name="tools"><Text>&amp;Tools</Text>
+ <Menu name="version_control"><Text>&amp;Version Control</Text>
+ <Merge/>
+ <Menu name="version_control_tools_subversion" group="tools_project_operations">
+ <Text>&amp;Subversion</Text>
+ <Action name="subversion_commit" />
+ <Action name="subversion_diff" />
+ <Action name="subversion_log" />
+ <Action name="subversion_add" />
+ <Action name="subversion_add_bin" />
+ <Action name="subversion_remove" />
+ <Separator />
+ <Action name="subversion_tag" />
+ <Action name="subversion_untag" />
+ <Action name="subversion_update" />
+ <Action name="subversion_removesticky" />
+ <Action name="subversion_revert" />
+ <Separator />
+ <Action name="subversion_ignore" />
+ <Action name="subversion_donot_ignore" />
+<!-- <Separator />
+ <Action name="subversion_login" />
+ <Action name="subversion_logout" /> -->
+ </Menu>
+ </Menu>
+ </Menu>
+</MenuBar>
+</kpartplugin>
diff --git a/vcs/subversion/kdevsubversion.desktop b/vcs/subversion/kdevsubversion.desktop
new file mode 100644
index 00000000..500b5fb0
--- /dev/null
+++ b/vcs/subversion/kdevsubversion.desktop
@@ -0,0 +1,34 @@
+[Desktop Entry]
+Type=Service
+Exec=blubb
+Comment=Subversion
+Comment[fa]=زیرنسخه
+Comment[hi]=सबवर्सन
+Comment[ne]=सबभर्सन
+Comment[pt_BR]=Subversão
+Comment[ru]=Интеграция Subversion
+Comment[ta]=உப பதிப்பு
+Comment[tg]=Интегратсия Subversion
+Name=KDevsubversion
+Name[da]=KDevelop Subversion
+Name[de]=Unterstützung für Subversion (KDevelop)
+Name[hi]=के-डेव-सबवर्सन
+Name[nds]=Subversion-Ünnerstütten för KDevelop
+Name[sk]=KDev Subversion
+Name[sv]=KDevelop Subversion
+Name[ta]=kdev உப பதிப்பு
+Name[tg]=KDevзер-ривоят
+Name[zh_TW]=KDevelop Subversion
+GenericName=Subversion
+GenericName[fa]=زیرنسخه
+GenericName[hi]=सबवर्सन
+GenericName[ne]=सबभर्सन
+GenericName[pt_BR]=Subversão
+GenericName[ru]=Интеграция Subversion
+GenericName[ta]=துணை பதிப்பு
+GenericName[tg]=Зер-ривоят
+Icon=misc
+ServiceTypes=KDevelop/VersionControl
+X-KDE-Library=libkdevsubversion
+X-KDevelop-Version=5
+X-KDevelop-Properties=VCS,SubversionVCS
diff --git a/vcs/subversion/kdevsvn+file.protocol b/vcs/subversion/kdevsvn+file.protocol
new file mode 100644
index 00000000..decc1cc4
--- /dev/null
+++ b/vcs/subversion/kdevsvn+file.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_kdevsvn
+protocol=kdevsvn+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 for KDevelop
+Description[ca]=L'esclau io (ioslave) Subversion per a KDevelop
+Description[de]=Ein-/Ausgabemodul für Subversion (KDevelop)
+Description[el]=Subversion ioslave για το KDevelop
+Description[es]=El ioslave de Subversion para KDevelop
+Description[et]=KDevelopi Subversioni IO-moodul
+Description[fr]=Esclave d'E/S (ioslave) Subversion pour KDevelop
+Description[hu]=Subversion KDE-protokoll a KDevelophoz
+Description[it]=ioslave di subversion per KDevelop
+Description[ja]=KDevelop のための Subversion ioslave
+Description[ms]=IOslave Subversion untuk KDevelop
+Description[nds]=KDevelop-In-/Utgaavmoduul för Subversion
+Description[nl]=Subversion-ioslave voor KDevelop
+Description[pl]=Wtyczka protokołu Subversion dla KDevelopa
+Description[pt]='Ioslave' do Subversion para o KDevelop
+Description[pt_BR]='Ioslave' do Subversion para o KDevelop
+Description[ru]=Поддержка протокола Subversion для KDevelop
+Description[sk]=Subversion ioslave pre KDevelop
+Description[sr]=KIOSlave Subversion-а за KDevelop
+Description[sr@Latn]=KIOSlave Subversion-a za KDevelop
+Description[sv]=Subversion I/O-slav för KDevelop
+Description[zh_TW]=KDevelop 的 Subversion ioslave
+maxInstances=5
+class=:internet
diff --git a/vcs/subversion/kdevsvn+http.protocol b/vcs/subversion/kdevsvn+http.protocol
new file mode 100644
index 00000000..5e836c02
--- /dev/null
+++ b/vcs/subversion/kdevsvn+http.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_kdevsvn
+protocol=kdevsvn+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 for KDevelop
+Description[ca]=L'esclau io (ioslave) Subversion per a KDevelop
+Description[de]=Ein-/Ausgabemodul für Subversion (KDevelop)
+Description[el]=Subversion ioslave για το KDevelop
+Description[es]=El ioslave de Subversion para KDevelop
+Description[et]=KDevelopi Subversioni IO-moodul
+Description[fr]=Esclave d'E/S (ioslave) Subversion pour KDevelop
+Description[hu]=Subversion KDE-protokoll a KDevelophoz
+Description[it]=ioslave di subversion per KDevelop
+Description[ja]=KDevelop のための Subversion ioslave
+Description[ms]=IOslave Subversion untuk KDevelop
+Description[nds]=KDevelop-In-/Utgaavmoduul för Subversion
+Description[nl]=Subversion-ioslave voor KDevelop
+Description[pl]=Wtyczka protokołu Subversion dla KDevelopa
+Description[pt]='Ioslave' do Subversion para o KDevelop
+Description[pt_BR]='Ioslave' do Subversion para o KDevelop
+Description[ru]=Поддержка протокола Subversion для KDevelop
+Description[sk]=Subversion ioslave pre KDevelop
+Description[sr]=KIOSlave Subversion-а за KDevelop
+Description[sr@Latn]=KIOSlave Subversion-a za KDevelop
+Description[sv]=Subversion I/O-slav för KDevelop
+Description[zh_TW]=KDevelop 的 Subversion ioslave
+maxInstances=5
+class=:internet
diff --git a/vcs/subversion/kdevsvn+https.protocol b/vcs/subversion/kdevsvn+https.protocol
new file mode 100644
index 00000000..af9301af
--- /dev/null
+++ b/vcs/subversion/kdevsvn+https.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_kdevsvn
+protocol=kdevsvn+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 for KDevelop
+Description[ca]=L'esclau io (ioslave) Subversion per a KDevelop
+Description[de]=Ein-/Ausgabemodul für Subversion (KDevelop)
+Description[el]=Subversion ioslave για το KDevelop
+Description[es]=El ioslave de Subversion para KDevelop
+Description[et]=KDevelopi Subversioni IO-moodul
+Description[fr]=Esclave d'E/S (ioslave) Subversion pour KDevelop
+Description[hu]=Subversion KDE-protokoll a KDevelophoz
+Description[it]=ioslave di subversion per KDevelop
+Description[ja]=KDevelop のための Subversion ioslave
+Description[ms]=IOslave Subversion untuk KDevelop
+Description[nds]=KDevelop-In-/Utgaavmoduul för Subversion
+Description[nl]=Subversion-ioslave voor KDevelop
+Description[pl]=Wtyczka protokołu Subversion dla KDevelopa
+Description[pt]='Ioslave' do Subversion para o KDevelop
+Description[pt_BR]='Ioslave' do Subversion para o KDevelop
+Description[ru]=Поддержка протокола Subversion для KDevelop
+Description[sk]=Subversion ioslave pre KDevelop
+Description[sr]=KIOSlave Subversion-а за KDevelop
+Description[sr@Latn]=KIOSlave Subversion-a za KDevelop
+Description[sv]=Subversion I/O-slav för KDevelop
+Description[zh_TW]=KDevelop 的 Subversion ioslave
+maxInstances=5
+class=:internet
diff --git a/vcs/subversion/kdevsvn+ssh.protocol b/vcs/subversion/kdevsvn+ssh.protocol
new file mode 100644
index 00000000..33a644f0
--- /dev/null
+++ b/vcs/subversion/kdevsvn+ssh.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_kdevsvn
+protocol=kdevsvn+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 for KDevelop
+Description[ca]=L'esclau io (ioslave) Subversion per a KDevelop
+Description[de]=Ein-/Ausgabemodul für Subversion (KDevelop)
+Description[el]=Subversion ioslave για το KDevelop
+Description[es]=El ioslave de Subversion para KDevelop
+Description[et]=KDevelopi Subversioni IO-moodul
+Description[fr]=Esclave d'E/S (ioslave) Subversion pour KDevelop
+Description[hu]=Subversion KDE-protokoll a KDevelophoz
+Description[it]=ioslave di subversion per KDevelop
+Description[ja]=KDevelop のための Subversion ioslave
+Description[ms]=IOslave Subversion untuk KDevelop
+Description[nds]=KDevelop-In-/Utgaavmoduul för Subversion
+Description[nl]=Subversion-ioslave voor KDevelop
+Description[pl]=Wtyczka protokołu Subversion dla KDevelopa
+Description[pt]='Ioslave' do Subversion para o KDevelop
+Description[pt_BR]='Ioslave' do Subversion para o KDevelop
+Description[ru]=Поддержка протокола Subversion для KDevelop
+Description[sk]=Subversion ioslave pre KDevelop
+Description[sr]=KIOSlave Subversion-а за KDevelop
+Description[sr@Latn]=KIOSlave Subversion-a za KDevelop
+Description[sv]=Subversion I/O-slav för KDevelop
+Description[zh_TW]=KDevelop 的 Subversion ioslave
+maxInstances=5
+class=:internet
diff --git a/vcs/subversion/kdevsvn+svn.protocol b/vcs/subversion/kdevsvn+svn.protocol
new file mode 100644
index 00000000..0f9ab069
--- /dev/null
+++ b/vcs/subversion/kdevsvn+svn.protocol
@@ -0,0 +1,39 @@
+[Protocol]
+exec=kio_kdevsvn
+protocol=kdevsvn+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 for KDevelop
+Description[ca]=L'esclau io (ioslave) Subversion per a KDevelop
+Description[de]=Ein-/Ausgabemodul für Subversion (KDevelop)
+Description[el]=Subversion ioslave για το KDevelop
+Description[es]=El ioslave de Subversion para KDevelop
+Description[et]=KDevelopi Subversioni IO-moodul
+Description[fr]=Esclave d'E/S (ioslave) Subversion pour KDevelop
+Description[hu]=Subversion KDE-protokoll a KDevelophoz
+Description[it]=ioslave di subversion per KDevelop
+Description[ja]=KDevelop のための Subversion ioslave
+Description[ms]=IOslave Subversion untuk KDevelop
+Description[nds]=KDevelop-In-/Utgaavmoduul för Subversion
+Description[nl]=Subversion-ioslave voor KDevelop
+Description[pl]=Wtyczka protokołu Subversion dla KDevelopa
+Description[pt]='Ioslave' do Subversion para o KDevelop
+Description[pt_BR]='Ioslave' do Subversion para o KDevelop
+Description[ru]=Поддержка протокола Subversion для KDevelop
+Description[sk]=Subversion ioslave pre KDevelop
+Description[sr]=KIOSlave Subversion-а за KDevelop
+Description[sr@Latn]=KIOSlave Subversion-a za KDevelop
+Description[sv]=Subversion I/O-slav för KDevelop
+Description[zh_TW]=KDevelop 的 Subversion ioslave
+maxInstances=5
+class=:internet
diff --git a/vcs/subversion/kdevsvnd.cpp b/vcs/subversion/kdevsvnd.cpp
new file mode 100644
index 00000000..9963cddd
--- /dev/null
+++ b/vcs/subversion/kdevsvnd.cpp
@@ -0,0 +1,394 @@
+/*
+ This file is part of the KDE Project
+
+ Copyright (C) 2003, 2004 Mickael Marchand <marchand@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ This software 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 library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+#include <ktextedit.h>
+#include <kpassdlg.h>
+#include <qdir.h>
+#include <qfile.h>
+
+#include "config.h"
+
+#include "kdevsvnd.h"
+
+#include "kdevsvnd_widgets.h"
+#include "commitdlg.h"
+
+extern "C" {
+ KDE_EXPORT KDEDModule *create_kdevsvnd(const QCString &name) {
+ return new KDevSvnd(name);
+ }
+}
+
+KDevSvnd::KDevSvnd(const QCString &name)
+ : KDEDModule(name) {
+}
+KDevSvnd::~KDevSvnd()
+{}
+
+QString KDevSvnd::commitDialog(QString modifiedFiles) {
+ CommitDlg commitDlg;
+ commitDlg.setCaption(i18n("Enter Commit Log Message:"));
+ commitDlg.listMessage->setText( modifiedFiles );
+ int result = commitDlg.exec();
+ if ( result == QDialog::Accepted ) {
+ return commitDlg.textMessage->text();
+ } else
+ return QString::null;
+}
+int KDevSvnd::sslServerTrustPrompt( QString errmsg, QString hostname, QString fingerPrint, QString validfrom, QString validuntil, QString issuerName, QString ascii_cert )
+{
+ SvnSSLTrustPrompt dlg;
+ dlg.setupCertInfo( hostname, fingerPrint, validfrom, validuntil, issuerName, ascii_cert );
+ dlg.setupFailedReasonMsg( errmsg );
+ int result = dlg.exec();
+ if ( result == QDialog::Accepted ){
+ return dlg.code();
+ } else{
+ return -1;
+ }
+}
+QString KDevSvnd::sslCertFile()
+{
+ QString fileName = KFileDialog::getOpenFileName(QString::null,QString::null,0, i18n("Open SSL certificate file"));
+ return fileName;
+}
+QCString KDevSvnd::sslPasswdDlg(QString promptMsg)
+{
+ QCString passwd;
+ int ret = KPasswordDialog::getPassword( passwd,promptMsg );
+ if( ret == KPasswordDialog::Accepted ){
+ QCString retstr;
+ retstr.setNum(1);
+ return retstr + passwd;
+ } else{
+ QCString nullstr;
+ nullstr.setNum(-1);
+ return nullstr;
+ }
+}
+
+
+// void KDevSvnd::registerMe(const QCString &app)
+// {
+// insert(app, "test", new TestObject(app));
+// // When 'app' unregisters with DCOP, the TestObject will get deleted.
+// }
+
+// bool KSvnd::AreAnyFilesInSvn( const KURL::List& wclist ) {
+// for ( QValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
+// kdDebug( 9036 ) << "Checking file " << ( *it ) << endl;
+// QDir bdir ( ( *it ).path() );
+// if ( bdir.exists() && QFile::exists( ( *it ).path() + "/.svn/entries" ) ) {
+// return true;
+// } else if ( !bdir.exists() ) {
+// if ( isFileInSvnEntries( ( *it ).fileName(), ( *it ).directory() + "/.svn/entries" ) || isFileInExternals ( ( *it ).fileName(), ( *it ).directory()+"/.svn/dir-props" ) )
+// return true;
+// }
+// }
+// return false;
+// }
+//
+// bool KSvnd::AreAnyFilesNotInSvn( const KURL::List& wclist ) {
+// for ( QValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
+// kdDebug( 9036 ) << "Checking file " << ( *it ) << endl;
+// QDir bdir ( ( *it ).path() );
+// if ( bdir.exists() && !QFile::exists( ( *it ).path() + "/.svn/entries" ) ) {
+// return true;
+// } else if ( !bdir.exists() ) {
+// if ( !isFileInSvnEntries( ( *it ).fileName(),( *it ).directory() + "/.svn/entries" ) && !isFileInExternals ( ( *it ).fileName(), ( *it ).directory()+"/.svn/dir-props" ) )
+// return true;
+// }
+// }
+// return false;
+// }
+//
+// bool KSvnd::AreAllFilesInSvn( const KURL::List& wclist ) {
+// for ( QValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
+// kdDebug( 9036 ) << "Checking file " << ( *it ) << endl;
+// QDir bdir ( ( *it ).path() );
+// if ( bdir.exists() && !QFile::exists( ( *it ).path() + "/.svn/entries" ) ) {
+// return false;
+// } else if ( !bdir.exists() ) {
+// if ( !isFileInSvnEntries( ( *it ).fileName(),( *it ).directory() + "/.svn/entries" ) && !isFileInExternals ( ( *it ).fileName(), ( *it ).directory()+"/.svn/dir-props" ) )
+// return false;
+// }
+// }
+// return true;
+// }
+//
+// bool KSvnd::AreAllFilesNotInSvn( const KURL::List& wclist ) {
+// for ( QValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
+// kdDebug( 9036 ) << "Checking file " << ( *it ) << endl;
+// QDir bdir ( ( *it ).path() );
+// if ( bdir.exists() && QFile::exists( ( *it ).path() + "/.svn/entries" ) ) {
+// return false;
+// } else if ( !bdir.exists() ) {
+// if ( isFileInSvnEntries( ( *it ).fileName(),( *it ).directory() + "/.svn/entries" ) || isFileInExternals ( ( *it ).fileName(), ( *it ).directory()+"/.svn/dir-props" ) )
+// return false;
+// }
+// }
+// return true;
+// }
+//
+// bool KSvnd::isFileInSvnEntries ( const QString filename, const QString entfile ) {
+// QFile file( entfile );
+// if ( file.open( IO_ReadOnly ) ) {
+// QTextStream stream( &file );
+// QString line;
+// while ( !stream.atEnd() ) {
+// line = stream.readLine().simplifyWhiteSpace();
+// if ( line == "name=\""+ filename + "\"" ) {
+// file.close();
+// return true;
+// }
+// }
+// file.close();
+// }
+// return false;
+// }
+//
+// bool KSvnd::isFileInExternals ( const QString filename, const QString propfile ) {
+// QFile file( propfile );
+// if ( file.open( IO_ReadOnly ) ) {
+// QTextStream stream( &file );
+// QStringList line;
+// while ( !stream.atEnd() )
+// line << stream.readLine().simplifyWhiteSpace();
+// for ( uint i = 0 ; i < line.count(); i++ ) {
+// if ( line[ i ] == "K 13" && line[ i+1 ] == "svn:externals" ) { //Key 13 : svn:externals
+// //next line should be "V xx"
+// if ( line [ i+2 ].startsWith( "V " ) ) {
+// //ok browse the values now
+// i+=2;
+// while ( i < line.count() ) {
+// if ( line[ i ].startsWith( filename+" " ) ) { //found it !
+// file.close( );
+// return true;
+// } else if ( line[ i ].isEmpty() ) {
+// file.close( );
+// return false; //we are out of svn:externals now...
+// }
+// i++;
+// }
+// }
+// }
+// }
+// file.close();
+// }
+// return false;
+// }
+//
+// bool KSvnd::anyNotValidWorkingCopy( const KURL::List& wclist ) {
+// bool result = true; //one negative match is enough
+// for ( QValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
+// //exception for .svn dirs
+// if ( ( *it ).path(-1).endsWith( "/.svn" ) )
+// return true;
+// //if is a directory check whether it contains a .svn/entries file
+// QDir dir( ( *it ).path() );
+// if ( dir.exists() ) { //it's a dir
+// if ( !QFile::exists( ( *it ).path() + "/.svn/entries" ) )
+// result = false;
+// }
+//
+// //else check if ./.svn/entries exists
+// if ( !QFile::exists( ( *it ).directory() + "/.svn/entries" ) )
+// result = false;
+// }
+// return result;
+// }
+//
+// bool KSvnd::anyValidWorkingCopy( const KURL::List& wclist ) {
+// for ( QValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
+// //skip .svn dirs
+// if ( ( *it ).path(-1).endsWith( "/.svn" ) )
+// continue;
+// //if is a directory check whether it contains a .svn/entries file
+// QDir dir( ( *it ).path() );
+// if ( dir.exists() ) { //it's a dir
+// if ( QFile::exists( ( *it ).path() + "/.svn/entries" ) )
+// return true;
+// }
+//
+// //else check if ./.svn/entries exists
+// if ( QFile::exists( ( *it ).directory() + "/.svn/entries" ) )
+// return true;
+// }
+// return false;
+// }
+//
+// int KSvnd::getStatus( const KURL::List& list ) {
+// int result = 0;
+// uint files = 0, folders = 0, parentsentries = 0, parentshavesvn = 0, subdirhavesvn = 0, external = 0;
+// for ( QValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
+// if ( isFolder ( ( *it ) ) ) {
+// folders++;
+// } else {
+// files++;
+// }
+// if ( isFileInSvnEntries ( (*it).filename(),( *it ).directory() + "/.svn/entries" ) ) { // normal subdir known in the working copy
+// parentsentries++;
+// } else if ( isFolder( *it ) ) { // other subfolders (either another module checkouted or an external, or something not known at all)
+// if ( QFile::exists( ( *it ).path() + "/.svn/entries" ) )
+// subdirhavesvn++;
+// if ( isFileInExternals( (*it).filename(), ( *it ).directory() + "/.svn/dir-props" ) ) {
+// external++;
+// }
+// }
+// if ( ( isFolder( ( *it ) ) && QFile::exists( ( *it ).directory() + "../.svn/entries" ) ) || QFile::exists( ( *it ).directory() + "/.svn/entries" ) ) //parent has a .svn ?
+// parentshavesvn++;
+// }
+// if ( files > 0 )
+// result |= SomeAreFiles;
+// if ( folders == list.count() ) {
+// result |= AllAreFolders;
+// result |= SomeAreFolders;
+// }
+// if ( folders > 0 )
+// result |= SomeAreFolders;
+// if ( parentsentries == list.count() ) {
+// result |= AllAreInParentsEntries;
+// result |= SomeAreInParentsEntries;
+// } else if ( parentsentries != 0 )
+// result |= SomeAreInParentsEntries;
+// if ( parentshavesvn == list.count() ) {
+// result |= AllParentsHaveSvn;
+// result |= SomeParentsHaveSvn;
+// } else if ( parentshavesvn > 0 )
+// result |= SomeParentsHaveSvn;
+// if ( subdirhavesvn == list.count() ) {
+// result |= AllHaveSvn;
+// result |= SomeHaveSvn;
+// } else if ( subdirhavesvn > 0 )
+// result |= SomeHaveSvn;
+// if ( external == list.count() ) {
+// result |= AllAreExternalToParent;
+// result |= SomeAreExternalToParent;
+// } else if ( external > 0 )
+// result |= SomeAreExternalToParent;
+//
+// return result;
+// }
+//
+// bool KSvnd::isFolder( const KURL& url ) {
+// QDir d( url.path() );
+// return d.exists();
+// }
+//
+// QStringList KSvnd::getActionMenu ( const KURL::List &list ) {
+// QStringList result;
+// int listStatus = getStatus( list );
+//
+// if ( !(listStatus & SomeAreInParentsEntries) &&
+// !(listStatus & SomeAreExternalToParent) &&
+// !(listStatus & SomeHaveSvn)) {
+// if( list.size() == 1 && listStatus & SomeAreFolders) {
+// result << "Checkout";
+// result << "Export";
+// // result << "CreateRepository";
+// result << "Import";
+// }
+// } else if ( (listStatus & AllAreInParentsEntries) ) {
+// result << "Diff";
+// //In SVN
+// // result << "ShowLog";
+// // result << "CheckForModifications";
+// // result << "RevisionGraph";
+// // result << "_SEPARATOR_";
+// // result << "Update to revision..."
+// result << "Rename";
+// result << "Delete";
+// if( listStatus & SomeAreFolders && !(listStatus & SomeAreFiles)) {
+// result << "Revert";
+// // result << "Cleanup";
+// }
+// result << "_SEPARATOR_";
+// // result << "BranchTag";
+// result << "Switch";
+// result << "Merge";
+// if( listStatus & SomeAreFolders && !(listStatus & SomeAreFiles)) {
+// // result << "Export";
+// // result << "Relocate";
+// result << "_SEPARATOR_";
+// result << "Add";
+// }
+// result << "_SEPARATOR_";
+// if( listStatus & SomeAreFiles && !(listStatus & SomeAreFolders)) {
+// result << "Blame";
+// }
+// result << "CreatePatch";
+//
+// if( list.size() == 1 && listStatus & SomeAreFolders) {
+// // result << "ApplyPatchToFolder";
+// }
+// }
+// return result;
+// }
+//
+// QStringList KSvnd::getTopLevelActionMenu ( const KURL::List &list ) {
+// QStringList result;
+// int listStatus = getStatus( list );
+//
+//
+// if ( ( listStatus & AllParentsHaveSvn &&
+// ( ( listStatus & SomeAreExternalToParent ) || ( listStatus & SomeAreInParentsEntries ) )
+// || ( listStatus & SomeHaveSvn ) )
+// ) {
+// result << "Update";
+// result << "Commit";
+// }
+//
+// return result;
+// }
+//
+// #if 0
+// void KSvnd::notify(const QString& path, int action, int kind, const QString& mime_type, int content_state, int prop_state, long int revision, const QString& userstring) {
+// kdDebug(9036) << "KDED/Subversion : notify " << path << " action : " << action << " mime_type : " << mime_type << " content_state : " << content_state << " prop_state : " << prop_state << " revision : " << revision << " userstring : " << userstring << endl;
+// QByteArray params;
+//
+// QDataStream stream(params, IO_WriteOnly);
+// stream << path << action << kind << mime_type << content_state << prop_state << revision << userstring;
+//
+// emitDCOPSignal( "subversionNotify(QString,int,int,QString,int,int,long int,QString)", params );
+// }
+//
+// void KSvnd::status(const QString& path, int text_status, int prop_status, int repos_text_status, int repos_prop_status, long int rev ) {
+// kdDebug(9036) << "KDED/Subversion : status " << path << " " << text_status << " " << prop_status << " "
+// << repos_text_status << " " << repos_prop_status << " " << rev << endl;
+// QByteArray params;
+//
+// QDataStream stream(params, IO_WriteOnly);
+// stream << path << text_status << prop_status << repos_text_status << repos_prop_status << rev;
+//
+// emitDCOPSignal( "subversionStatus(QString,int,int,int,int,long int)", params );
+// }
+//
+// void KSvnd::popupMessage( const QString& message ) {
+// kdDebug(9036) << "KDED/Subversion : popupMessage" << message << endl;
+// KMessageBox::information(0, message, i18n( "Subversion" ) );
+// }
+// #endif
+
+#include "kdevsvnd.moc"
diff --git a/vcs/subversion/kdevsvnd.desktop b/vcs/subversion/kdevsvnd.desktop
new file mode 100644
index 00000000..139350f5
--- /dev/null
+++ b/vcs/subversion/kdevsvnd.desktop
@@ -0,0 +1,31 @@
+[Desktop Entry]
+Type=Service
+Name=KDevelop subversion module
+Name[ca]=Mòdul de Subversion per a KDevelop
+Name[da]=KDevelop Subversion-modul
+Name[de]=Subversion-Komponente (KDevelop)
+Name[el]=Άρθρωμα subversion του KDevelop
+Name[es]=Módulo de Subversion de KDevelop
+Name[et]=KDevelopi Subversioni moodul
+Name[fr]=Module Subversion pour KDevelop
+Name[hu]=KDevelop-modul a Subversion kezeléséhez
+Name[it]=Modulo subversion di KDevelop
+Name[ja]=KDevelop Subversion モジュール
+Name[ms]=Modul Subversion KDevelop
+Name[nds]=KDevelop-Moduul för Subversion
+Name[nl]=KDevelop subversion-module
+Name[pl]=Modul Subversion dla KDevelopa
+Name[pt]=Módulo de Subversion do KDevelop
+Name[pt_BR]=Módulo de Subversion do KDevelop
+Name[ru]=Модуль Subversion для KDevelop
+Name[sk]=KDevelop subversion modul
+Name[sr]=KDevelop-ов модул за Subversion
+Name[sr@Latn]=KDevelop-ov modul za Subversion
+Name[sv]=KDevelop Subversion-modul
+Name[zh_TW]=KDevelop Subversion 模組
+ServiceTypes=KDEDModule
+X-KDE-ModuleType=Library
+X-KDE-Library=kdevsvnd
+X-KDE-FactoryName=kdevsvnd
+X-KDE-Kded-autoload=true
+X-KDE-Kded-load-on-demand=true
diff --git a/vcs/subversion/kdevsvnd.h b/vcs/subversion/kdevsvnd.h
new file mode 100644
index 00000000..ad718f0c
--- /dev/null
+++ b/vcs/subversion/kdevsvnd.h
@@ -0,0 +1,50 @@
+/*
+ This file is part of the KDE Project
+
+ Copyright (C) 2003-2005 Mickael Marchand <marchand@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ This software 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 library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef KSVND_H
+#define KSVND_H
+
+#include <dcopclient.h>
+#include <kdedmodule.h>
+#include <kurl.h>
+#include <qstringlist.h>
+
+class KDevSvnd : public KDEDModule
+{
+Q_OBJECT
+
+K_DCOP
+
+ //note: InSVN means parent is added. InRepos means itself is added
+ enum { SomeAreFiles = 1, SomeAreFolders = 2, SomeAreInParentsEntries = 4, SomeParentsHaveSvn = 8, SomeHaveSvn = 16, SomeAreExternalToParent = 32, AllAreInParentsEntries = 64, AllParentsHaveSvn = 128, AllHaveSvn = 256, AllAreExternalToParent = 512, AllAreFolders = 1024 };
+public:
+ KDevSvnd(const QCString &);
+ ~KDevSvnd();
+
+k_dcop:
+// void addAuthInfo(KIO::AuthInfo, long);
+ QString commitDialog(QString);
+ int sslServerTrustPrompt(QString certFailMsg, QString hostname, QString fingerPrint, QString validfrom, QString validuntil, QString issuerName, QString ascii_cert );
+ QString sslCertFile();
+ QCString sslPasswdDlg(QString promptMsg);
+
+};
+
+#endif
diff --git a/vcs/subversion/kdevsvnd_widgets.cpp b/vcs/subversion/kdevsvnd_widgets.cpp
new file mode 100644
index 00000000..16e35ce3
--- /dev/null
+++ b/vcs/subversion/kdevsvnd_widgets.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library General Public License for more details.
+ */
+
+#include "kdevsvnd_widgets.h"
+#include <qpushbutton.h>
+#include <qlistview.h>
+#include <qlabel.h>
+#include <klocale.h>
+
+SvnSSLTrustPrompt::SvnSSLTrustPrompt( QWidget* parent, const char* name, bool modal, WFlags f )
+ :SvnSSLTrustPromptBase( parent, name, modal, f )
+ , m_code(-1)
+{
+ listView1->setColumnText( 0, "Items" );
+ listView1->setColumnText( 1, "Values" );
+ btnPermanent->setText(i18n("Accept Permanently"));
+ btnTemporary->setText(i18n("Accept Temporarily"));
+ btnReject->setText(i18n("Reject"));
+ connect( btnPermanent, SIGNAL(clicked()), this, SLOT(setPermanent()) );
+ connect( btnTemporary, SIGNAL(clicked()), this, SLOT(setTemporary()) );
+ connect( btnReject, SIGNAL(clicked()), this, SLOT(setRejected ()) );
+}
+SvnSSLTrustPrompt::~SvnSSLTrustPrompt()
+{}
+
+void SvnSSLTrustPrompt::setupCertInfo( QString hostname, QString fingerPrint, QString validfrom, QString validuntil, QString issuerName, QString ascii_cert )
+{
+ // setup texts
+ QListViewItem *host= new QListViewItem(listView1, i18n("Hostname"), hostname );
+ QListViewItem *finger = new QListViewItem(listView1, i18n("FingerPrint"), fingerPrint );
+ QListViewItem *validFrom = new QListViewItem(listView1, i18n("Valid From"), validfrom );
+ QListViewItem *validUntil = new QListViewItem(listView1, i18n("Valid Until"), validuntil );
+ QListViewItem *issName = new QListViewItem(listView1, i18n("Issuer"), issuerName );
+ QListViewItem *cert = new QListViewItem(listView1, i18n("Cert"), ascii_cert );
+}
+void SvnSSLTrustPrompt::setupFailedReasonMsg( QString msg )
+{
+ errMsgLabel->setText( msg );
+}
+int SvnSSLTrustPrompt::code()
+{
+ return m_code;
+}
+
+void SvnSSLTrustPrompt::setPermanent()
+{
+ m_code = 1;
+}
+
+void SvnSSLTrustPrompt::setTemporary()
+{
+ m_code = 0;
+}
+
+void SvnSSLTrustPrompt::setRejected()
+{
+ m_code = -1;
+}
+#include "kdevsvnd_widgets.moc"
diff --git a/vcs/subversion/kdevsvnd_widgets.h b/vcs/subversion/kdevsvnd_widgets.h
new file mode 100644
index 00000000..c69fdb14
--- /dev/null
+++ b/vcs/subversion/kdevsvnd_widgets.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library General Public License for more details.
+ */
+
+#ifndef KDEVSVND_WIDGETS_H
+#define KDEVSVND_WIDGETS_H
+
+#include "svnssltrustpromptbase.h"
+
+class SvnSSLTrustPrompt : public SvnSSLTrustPromptBase{
+Q_OBJECT
+public:
+ SvnSSLTrustPrompt( QWidget* parent=0, const char* name=0, bool modal=true, WFlags f=0 );
+ ~SvnSSLTrustPrompt();
+ void setupCertInfo( QString hostname, QString fingerPrint, QString validfrom, QString validuntil, QString issuerName, QString ascii_cert );
+ void setupFailedReasonMsg( QString msg );
+ int code();
+
+public slots:
+ void setPermanent();
+ void setTemporary();
+ void setRejected();
+
+protected:
+ // -1 for reject
+ // 0 for accept temporarily
+ // 1 for accept permanently
+ int m_code;
+};
+
+#endif
diff --git a/vcs/subversion/subversion_core.cpp b/vcs/subversion/subversion_core.cpp
new file mode 100644
index 00000000..0a91d349
--- /dev/null
+++ b/vcs/subversion/subversion_core.cpp
@@ -0,0 +1,738 @@
+/**
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+#include <kparts/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 <kio/job.h>
+#include <kio/jobclasses.h>
+#include <kio/netaccess.h>
+#include <kdebug.h>
+#include <kmainwindow.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <ktempfile.h>
+#include <kprocess.h>
+#include <kstandarddirs.h>
+#include <qtextcodec.h>
+#include <qtextstream.h>
+#include <qtextbrowser.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <qregexp.h>
+
+#include <kapplication.h>
+#include <kinstance.h>
+#include <kaboutdata.h>
+
+using namespace KIO;
+using namespace SvnGlobal;
+
+subversionCore::subversionCore(subversionPart *part)
+// : QObject(NULL, "subversion core"), DCOPObject("subversion") {
+ : QObject(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(QString,int,int,QString,int,int,long int,QString)", "notification(QString,int,int,QString,int,int,long int,QString)", 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 QString& path, int action, int kind, const QString& mime_type, int content_state ,int prop_state ,long int revision, const QString& 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 ( QValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
+ kdDebug(9036) << "resolving: " << (*it).prettyURL() << endl;
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 11;
+ bool recurse = true;
+ s << cmd << *it << recurse;
+ SimpleJob * job = KIO::special(servURL, parms, true);
+ job->setWindow( m_part->mainWindow()->main() );
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+ }
+}
+
+void subversionCore::update( const KURL::List& list ) {
+ KURL servURL = "kdevsvn+svn://blah/";
+ kdDebug(9036) << "Updating. servURL : " << servURL.prettyURL() << endl;
+
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 2;
+ int rev = -1;
+ s << cmd << list << rev << QString( "HEAD" );
+
+ SimpleJob * job = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+ initProcessDlg( (KIO::Job*)job, i18n("Subversion Update") , i18n("Subversion Update") );
+}
+
+void subversionCore::diff( const KURL::List& list, const QString& where){
+ kdDebug(9036) << "diff " << list << endl;
+ KURL servURL = "kdevsvn+svn://this_is_a_fake_URL_and_this_is_normal/";
+ for ( QValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 13;
+ kdDebug(9036) << "diffing : " << (*it).prettyURL() << endl;
+ int rev1=-1;
+ int rev2=-1;
+ QString revkind1 = where;
+ QString revkind2 = "WORKING";
+ s << cmd << *it << *it << rev1 << revkind1 << rev2 << revkind2 << true ;
+ KIO::SimpleJob * job = KIO::special(servURL, parms, true);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+ KIO::NetAccess::synchronousRun( job, 0 );
+ if ( diffresult.count() > 0 ) {
+ //check kompare is available
+ if ( !KStandardDirs::findExe( "kompare" ).isNull() ) {
+ if (!KStandardDirs::findExe("patch").isNull()){
+ // we have patch - so can merge
+ KTempDir tmpDir = KTempDir(diffTmpDir->name());
+ KTempFile tmpPatch = KTempFile(tmpDir.name());
+
+ // write the patch
+ QTextStream *stream = tmpPatch.textStream();
+ stream->setCodec( QTextCodec::codecForName( "utf8" ) );
+ for ( QStringList::Iterator it2 = diffresult.begin();it2 != diffresult.end() ; ++it2 ) {
+ ( *stream ) << ( *it2 ) << "\n";
+ }
+ tmpPatch.close();
+
+ QString ourCopy = tmpDir.name()+(*it).fileName();
+
+ KProcess copy;
+ copy << "cp" << (*it).prettyURL(0,KURL::StripFileProtocol) << tmpDir.name();
+ copy.start(KProcess::Block);
+
+ KProcess patch;
+ patch.setWorkingDirectory(tmpDir.name());
+ patch << "patch" << "-R" << ourCopy << tmpPatch.name();
+ patch.start(KProcess::Block, KProcess::All);
+
+ KProcess *p = new KProcess;
+ *p << "kompare" << ourCopy << (*it).prettyURL();
+ p->start();
+ }
+ else{
+ // only diff
+ KTempFile *tmp = new KTempFile;
+ tmp->setAutoDelete(true);
+ QTextStream *stream = tmp->textStream();
+ stream->setCodec( QTextCodec::codecForName( "utf8" ) );
+ for ( QStringList::Iterator it2 = diffresult.begin();it2 != diffresult.end() ; ++it2 ) {
+ ( *stream ) << ( *it2 ) << "\n";
+ }
+ tmp->close();
+ KProcess *p = new KProcess;
+ *p << "kompare" << "-n" << "-o" << tmp->name();
+ p->start();
+ }
+ } else { //else do it with message box
+ Subversion_Diff df;
+ for ( QStringList::Iterator it2 = diffresult.begin();it2 != diffresult.end() ; ++it2 ) {
+ df.text->append( *it2 );
+ }
+ QFont f = df.font();
+ f.setFixedPitch( true );
+ df.text->setFont( f );
+ df.exec();
+ }
+ }
+ else{
+ QString 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, QString revKind1, int rev2, QString revKind2,
+ bool recurse, bool pegdiff )
+{
+ KURL servURL = "kdevsvn+svn://blah/";
+ QByteArray parms;
+ QDataStream 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;
+ KIO::SimpleJob * job = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotDiffResult( KIO::Job * ) ) );
+ initProcessDlg( (KIO::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;
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 103;
+ s << cmd << recurse << keeplocks;
+ for ( QValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
+ kdDebug(9036) << "adding to list: " << (*it).prettyURL() << endl;
+ s << *it;
+ }
+ SimpleJob * job = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+ if( list.count() == 1 )
+ initProcessDlg( (KIO::Job*)job, (*(list.begin())).prettyURL() , i18n("Commit to remote repository") );
+ else if( list.count() > 1 )
+ initProcessDlg( (KIO::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, QString revKindStart, int revend, QString 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;
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ // prepare arguments
+ int cmd = 4;
+// int revstart = -1, revend = 0;
+// QString revKindStart = "HEAD", revKindEnd = "";
+// bool repositLog = true, discorverChangedPath = true, strictNodeHistory = true;
+ s << cmd << revstart << revKindStart << revend << revKindEnd;
+ s << discorverChangedPath << strictNodeHistory;
+ for ( QValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
+ kdDebug(9036) << "svnCore: adding to list: " << (*it).prettyURL() << endl;
+ s << *it;
+ }
+ SimpleJob * job = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotLogResult( KIO::Job * ) ) );
+ // progress info. LogView is allowed and meaninful only for one url in KDev3.4
+ initProcessDlg( (KIO::Job*)job, (*(list.begin())).prettyURL() , i18n("Subversion Log View") );
+}
+
+void subversionCore::blame( const KURL &url, UrlMode mode, int revstart, QString revKindStart, int revend, QString 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;
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ // prepare arguments
+ int cmd = 14;
+ s << cmd << url << (int)mode ;
+ s << revstart << revKindStart << revend << revKindEnd ;
+
+ SimpleJob * job = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotBlameResult( KIO::Job * ) ) );
+ initProcessDlg( (KIO::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;
+
+ QByteArray parms;
+ QDataStream 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 = KIO::special(servURL, parms, false);
+ job->setWindow( m_part->mainWindow()->main() );
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+}
+
+void subversionCore::del( const KURL::List& list ) {
+ KURL servURL = "kdevsvn+svn://blah/";
+ kdDebug(9036) << "Deleting servURL : " << servURL.prettyURL() << endl;
+
+ QByteArray parms;
+ QDataStream 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 = KIO::special(servURL, parms, false);
+ job->setWindow( m_part->mainWindow()->main() );
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+}
+
+void subversionCore::revert( const KURL::List& list ) {
+ KURL servURL = "kdevsvn+svn://blah/";
+ kdDebug(9036) << "Reverting servURL : " << servURL.prettyURL() << endl;
+
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 8;
+ s << cmd << list;
+ SimpleJob * job = KIO::special(servURL, parms, false);
+ job->setWindow( m_part->mainWindow()->main() );
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+}
+
+void subversionCore::checkout() {
+ svn_co checkoutDlg;
+
+ if ( checkoutDlg.exec() == QDialog::Accepted ) {
+ //checkout :)
+ QByteArray parms;
+ QDataStream 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 << QString( "HEAD" );
+ servURL.setProtocol( "kdevsvn+" + servURL.protocol() ); //make sure it starts with "svn"
+ SimpleJob * job = KIO::special(servURL,parms, true);
+ job->setWindow( m_part->mainWindow()->main() );
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotEndCheckout( KIO::Job * ) ) );
+ }
+}
+
+void subversionCore::switchTree( const KURL &path, const KURL &repositUrl,
+ int revNum, const QString &revKind, bool recurse )
+{
+ KURL servURL = "kdevsvn+svn://blah/";
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ // prepare arguments
+ int cmd = 12;
+ s << cmd << path << repositUrl ;
+ s << recurse << revNum << revKind;
+
+ SimpleJob * job = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+ initProcessDlg( (KIO::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/";
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ // prepare arguments
+ int cmd = 16;
+ s << cmd << path << currentUrl << newUrl << recurse;
+
+ SimpleJob * job = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+ // this doesn't contact repository
+}
+
+void subversionCore::svnCopy( const KURL &src, int srcRev, const QString &srcRevKind,
+ const KURL &dest )
+{
+ KURL servURL = "kdevsvn+svn://blah/";
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ // prepare arguments
+ int cmd = 17;
+ s << cmd << src << srcRev << srcRevKind << dest;
+
+ SimpleJob * job = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+ initProcessDlg( (KIO::Job*)job, src.prettyURL(), dest.prettyURL() );
+}
+
+void subversionCore::merge( const KURL &src1, int rev1, QString revKind1,
+ const KURL &src2, int rev2, QString revKind2, const KURL &wc_path,
+ bool recurse, bool ignore_ancestry, bool force, bool dry_run )
+{
+ KURL servURL = "kdevsvn+svn://blah/";
+ QByteArray parms;
+ QDataStream 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 = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+ initProcessDlg( (KIO::Job*)job, src1.prettyURL() + "\n" + src2.prettyURL() ,
+ wc_path.prettyURL() );
+}
+
+bool subversionCore::clientInfo( KURL path_or_url, bool recurse, QMap< KURL, SvnInfoHolder> &holderMap )
+{
+ KURL servURL = "kdevsvn+svn://blah/";
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 15;
+ s << cmd << path_or_url << -1 << QString("UNSPECIFIED") << -1 << QString("UNSPECIFIED") << recurse;
+ SimpleJob *job = KIO::special( servURL, parms, false );
+
+ QMap<QString,QString> ma;
+ KIO::NetAccess::synchronousRun(job, 0, 0, 0, &ma ); // synchronize
+
+ QValueList<QString> keys = ma.keys();
+ QValueList<QString>::Iterator begin = keys.begin(), end = keys.end(), it;
+ int curIdx, lastIdx;
+ QRegExp 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( KIO::Job * job ) {
+ if ( job->error() ) {
+ job->showErrorDialog( m_part->mainWindow()->main() );
+ emit checkoutFinished( QString::null );
+ } else
+ emit checkoutFinished(wcPath);
+}
+
+void subversionCore::slotResult( KIO::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 KDevelop,"
+ " and the error message was 'unknown protocol kdevsvn+*',"
+ " try restarting KDE."
+ ) );
+ return;
+ }
+ KIO::MetaData ma = job->metaData();
+ QValueList<QString> keys = ma.keys();
+ qHeapSort( keys );
+ QValueList<QString>::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( KIO::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 KDevelop,"
+ " and the error message was 'unknown protocol kdevsvn+*',"
+ " try restarting KDE."
+ ) );
+ return;
+ }
+
+ QValueList<SvnLogHolder> holderList;
+
+ KIO::MetaData ma = job->metaData();
+ QValueList<QString> keys = ma.keys();
+ QRegExp rx( "([0-9]*)(.*)" );
+ int curIdx, lastIdx;
+ QString requestedUrl;
+
+ for (QValueList<QString>::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( KIO::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 KDevelop,"
+ " and the error message was 'unknown protocol kdevsvn+*',"
+ " try restarting KDE."
+ ) );
+ return;
+ }
+ QValueList<SvnBlameHolder> blameList;
+
+ KIO::MetaData ma = job->metaData();
+ QValueList<QString> keys = ma.keys();
+ QRegExp rx( "([0-9]*)(.*)" );
+ int curIdx, lastIdx;
+
+ for (QValueList<QString>::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( KIO::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 KDevelop,"
+ " and the error message was 'unknown protocol kdevsvn+*',"
+ " try restarting KDE."
+ ) );
+ return;
+ }
+ KIO::MetaData ma = job->metaData();
+ QValueList<QString> keys = ma.keys();
+ qHeapSort( keys );
+ QValueList<QString>::Iterator begin = keys.begin(), end = keys.end(), it;
+ QStringList 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 ( !KStandardDirs::findExe( "kompare" ).isNull() ) {
+ KTempFile *tmp = new KTempFile;
+ tmp->setAutoDelete(true);
+ QTextStream *stream = tmp->textStream();
+ stream->setCodec( QTextCodec::codecForName( "utf8" ) );
+ for ( QStringList::Iterator it2 = diffList.begin();it2 != diffList.end() ; ++it2 ) {
+ ( *stream ) << ( *it2 ) << "\n";
+ }
+ tmp->close();
+ KProcess *p = new KProcess;
+ *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/" , QString::null , "userDoesNotWantKompare" );
+ Subversion_Diff df;
+ for ( QStringList::Iterator it2 = diffList.begin();it2 != diffList.end() ; ++it2 ) {
+ df.text->append( *it2 );
+ }
+ QFont f = df.font();
+ f.setFixedPitch( true );
+ df.text->setFont( f );
+ df.exec();
+ }
+ }
+ else{
+ KMessageBox::information( 0, i18n("No subversion differences") );
+ }
+}
+
+void subversionCore::initProcessDlg( KIO::Job *job, const QString &src, const QString &dest )
+{
+ SvnProgressDlg *progress = new SvnProgressDlg( true );
+ progress->setSourceUrl( src );
+ progress->setDestUrl( dest );
+ progress->setJob( job );
+ connect( job, SIGNAL( totalSize(KIO::Job*, KIO::filesize_t) ),
+ progress, SLOT( slotTotalSize (KIO::Job*, KIO::filesize_t) ) );
+ connect( job, SIGNAL( processedSize(KIO::Job*, KIO::filesize_t) ),
+ progress, SLOT( slotProcessedSize(KIO::Job*, KIO::filesize_t) ) );
+}
+
+void subversionCore::createNewProject( const QString& // dirName
+ , const KURL& // importURL
+ , bool // init
+ ) {
+
+}
+
+#include "subversion_core.moc"
diff --git a/vcs/subversion/subversion_core.h b/vcs/subversion/subversion_core.h
new file mode 100644
index 00000000..c879fce6
--- /dev/null
+++ b/vcs/subversion/subversion_core.h
@@ -0,0 +1,105 @@
+/**
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SUBVERSION_CORE_H__
+#define __SUBVERSION_CORE_H__
+
+#include <qobject.h>
+#include <qwidget.h>
+#include <kio/job.h>
+#include <kurl.h>
+#include <ktempdir.h>
+#include "subversion_fileinfo.h"
+#include "subversion_global.h"
+
+class KDevProject;
+class subversionPart;
+class subversionWidget;
+class KApplication;
+class SvnBlameHolder;
+class SvnLogHolder;
+class SvnLogViewWidget;
+
+// class subversionCore : public QObject, public DCOPObject
+class subversionCore : public QObject {
+ Q_OBJECT
+// K_DCOP
+
+public:
+
+ subversionCore(subversionPart *part);
+ ~subversionCore();
+ subversionWidget *processWidget() const;
+// SvnLogViewWidget *processWidget() const;
+ void update( const KURL::List&);
+ void commit( const KURL::List&, bool recurse, bool keeplocks );
+ void svnLog( const KURL::List& list,
+ int revstart, QString revKindStart, int revend, QString revKindEnd,
+ bool discorverChangedPath, bool strictNodeHistory );
+ void blame( const KURL &url, SvnGlobal::UrlMode mode, int revstart, QString revKindStart, int revend, QString revKindEnd );
+ void add( const KURL::List&);
+ void del( const KURL::List&);
+ void diff( const KURL::List&, const QString& where);
+ void diffAsync( const KURL &pathOrUrl1, const KURL &pathOrUrl2,
+ int rev1, QString revKind1, int rev2, QString revKind2,
+ bool recurse, bool pegdiff = false );
+ void revert( const KURL::List&);
+ void resolve( const KURL::List&);
+ void checkout();
+ void switchTree( const KURL &path, const KURL &repositUrl,
+ int revNum, const QString &revKind, bool recurse );
+ void switchRelocate( const KURL &path, const KURL &currentUrl, const KURL &newUrl, bool recurse );
+ void svnCopy( const KURL &src, int srcRev, const QString &srcRevKind, const KURL &dest );
+ void merge( const KURL &src1, int rev1, QString revKind1, const KURL &src2, int rev2, QString revKind2, const KURL &wc_path,
+ bool recurse, bool ignore_ancestry, bool force, bool dry_run );
+ // This is blocking function. But the GUI is not blocked.
+ // Information will be pulled solely from the working copy.Thus no network connections will be made.
+ // Parameter holderMap is the map to be filled out by this method. Callers should preallocate this object.
+ // Return true on success. Otherwise return false.
+ bool clientInfo( KURL path_or_url, bool recurse, QMap< KURL, SvnGlobal::SvnInfoHolder> &holderMap );
+ void createNewProject( const QString& dirName, const KURL& importURL, bool init );
+ KDevVCSFileInfoProvider *fileInfoProvider() const;
+
+ void initProcessDlg( KIO::Job *job, const QString &src, const QString &dest );
+// k_dcop:
+// void notification( const QString&, int,int, const QString&, int,int ,long int, const QString& );
+
+private slots:
+ void slotEndCheckout( KIO::Job * job );
+ void slotResult( KIO::Job * job );
+ void slotLogResult( KIO::Job * job );
+ void slotBlameResult( KIO::Job * job );
+ void slotDiffResult( KIO::Job * job );
+
+signals:
+ void checkoutFinished( QString dir );
+
+private:
+ QGuardedPtr<subversionWidget> m_widget;
+ subversionPart *m_part;
+ QString wcPath;
+ SVNFileInfoProvider *m_fileInfoProvider;
+ QStringList diffresult; //for diff commands ;)
+ // be nice about tmp diff files: delete all of them when exiting.
+ KTempDir* diffTmpDir;
+
+};
+
+#endif
diff --git a/vcs/subversion/subversion_fileinfo.cpp b/vcs/subversion/subversion_fileinfo.cpp
new file mode 100644
index 00000000..c9fb9ee6
--- /dev/null
+++ b/vcs/subversion/subversion_fileinfo.cpp
@@ -0,0 +1,507 @@
+/**
+ Copyright (C) 2004-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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+#include "subversion_fileinfo.h"
+#include "subversion_core.h"
+#include <kdebug.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <kdevproject.h>
+#include <unistd.h>
+#include <kapplication.h>
+#include <kdevmainwindow.h>
+#include <kmainwindow.h>
+#include <qregexp.h>
+
+#include <kio/netaccess.h>
+#include <klocale.h>
+
+SVNFileInfoProvider::SVNFileInfoProvider(subversionPart *parent, const char *name)
+ : KDevVCSFileInfoProvider( parent, "svnfileinfoprovider" ),
+ m_cachedDirEntries( 0 ), m_recursiveDirEntries(0) {
+ Q_UNUSED(name);
+ m_part = parent;
+}
+
+SVNFileInfoProvider::~SVNFileInfoProvider() {
+ delete m_cachedDirEntries;
+ m_cachedDirEntries = 0;
+ delete m_recursiveDirEntries;
+ m_recursiveDirEntries = 0;
+}
+
+//synchronous
+const VCSFileInfoMap *SVNFileInfoProvider::status( const QString &dirPath ) {
+ if ( !m_cachedDirEntries )
+ m_cachedDirEntries = new VCSFileInfoMap;
+// return m_cachedDirEntries;
+
+ kdDebug(9036) << "svn provider : status " << dirPath << endl;
+
+ if ( dirPath != m_previousDirPath ) {
+ m_previousDirPath = dirPath;
+ KURL servURL = "kdevsvn+http://fakeserver_this_is_normal_behavior/";
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 9;
+ QString rPath = projectDirectory( );
+ rPath += QDir::separator() + dirPath;
+ kdDebug(9036) << "DIR : " << rPath << " " << KURL( QFileInfo( rPath ).absFilePath() ) << endl;
+
+// s << cmd << KURL( QFileInfo( rPath ).absFilePath() ) << true << true; //original line
+
+ // Dukju Ahn: if checkRepos is set, status() accesses remote repository,
+ // which causes significant delaym_owner especially when network speed is not fast enough.
+ // Of course, the user cannot get information about the out-of-dateness of his local copy.
+ s << cmd << KURL( QFileInfo( rPath ).absFilePath() ) << false/*checkRepos*/ << false /*fullRecurse*/;
+
+ KIO::SimpleJob *job2 = KIO::special(servURL, parms, false);
+ job2->setWindow( m_part->mainWindow()->main() );
+
+
+ QMap<QString,QString> ma;
+
+ KIO::NetAccess::synchronousRun(job2, m_part->mainWindow()->main(), 0, 0, &ma );
+
+ QValueList<QString> keys = ma.keys();
+ qHeapSort( keys );
+ QValueList<QString>::Iterator begin = keys.begin(), end = keys.end(), it;
+
+ QString path;
+ int text_status = 0, prop_status = 0, repos_text_status = 0, repos_prop_status = 0;
+ long int rev = 0;
+ int curIdx, lastIdx;
+
+ QRegExp rx( "([0-9]*)(.*)" );
+ for ( it = begin; it != end; ) {
+ kdDebug(9036) << "METADATA : " << *it << ":" << ma[ *it ] << endl;
+ if ( rx.search( *it ) == -1 ) return m_cachedDirEntries; // something is wrong ! :)
+ /* if some notification comes here, consume these notification metadatas */
+ if ( rx.cap( 2 ) == "action" ){
+ curIdx = lastIdx = rx.cap( 1 ).toInt();
+ while ( curIdx == lastIdx ){
+ ++it;
+ if ( it == end ) break;
+ if ( rx.search( *it ) == -1 ) continue; // something is wrong
+ curIdx = rx.cap( 1 ).toInt();
+ }
+ continue;
+ }
+ curIdx = lastIdx = rx.cap( 1 ).toInt();
+ while ( curIdx == lastIdx ) {
+ if ( rx.cap( 2 ) == "path" )
+ path = ma[ *it ];
+ else if ( rx.cap( 2 ) == "text" )
+ text_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "prop" )
+ prop_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "reptxt" )
+ repos_text_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "repprop" )
+ repos_prop_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "rev" )
+ rev = ma[ *it ].toLong();
+ ++it;
+ if ( it == end )
+ break;
+ if ( rx.search( *it ) == -1 ) break; // something is wrong ! :)
+ curIdx = rx.cap( 1 ).toInt();
+ }
+ slotStatus(path, text_status, prop_status, repos_text_status, repos_prop_status, rev);
+ }
+ }
+ kdDebug(9036) << " Returning VcsFileInfoMap. provider::status() finished " << endl;
+ return m_cachedDirEntries;
+}
+
+bool SVNFileInfoProvider::requestStatus( const QString &dirPath, void *callerData, bool recursive, bool checkRepos ) {
+ kdDebug(9036) << "##################################################################################### svn provider : request status" << endl;
+ m_savedCallerData = callerData;
+ // Flush old cache
+ if (m_cachedDirEntries)
+ {
+ delete m_cachedDirEntries;
+ m_cachedDirEntries = 0;
+ m_previousDirPath = dirPath;
+ }
+
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 9;
+ QString rPath = projectDirectory( );
+ rPath += QDir::separator() + dirPath;
+
+ if( ! m_part->isValidDirectory( rPath ) ){
+ return false;
+ }
+
+ kdDebug(9036) << "DIR : " << rPath << " " << QFileInfo( rPath ).absFilePath() << endl;
+ s << cmd << KURL( QFileInfo( rPath ).absFilePath() ) << checkRepos << recursive;
+ KURL servURL = "kdevsvn+http://fakeserver_this_is_normal_behavior/";
+ job = KIO::special(servURL, parms, false);
+ connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotResult( KIO::Job * ) ) );
+ if( checkRepos )
+ m_part->svncore()->initProcessDlg( job, dirPath, i18n("Subversion File/Directory Status") );
+ return true;
+}
+
+void SVNFileInfoProvider::slotResult( KIO::Job *j ) {
+ if ( j->error() )
+ j->showErrorDialog( m_part->mainWindow()->main() );
+
+ KIO::MetaData ma = j->metaData();
+ QValueList<QString> keys = ma.keys();
+ qHeapSort( keys );
+ QValueList<QString>::Iterator begin = keys.begin(), end = keys.end(), it;
+
+ QString path;
+ int text_status = 0, prop_status = 0, repos_text_status = 0, repos_prop_status = 0;
+ long int rev = 0;
+ int curIdx, lastIdx;
+
+ QRegExp rx( "([0-9]*)(.*)" );
+ for ( it = begin; it != end; ) {
+ kdDebug(9036) << "METADATA : " << *it << ":" << ma[ *it ] << endl;
+ if ( rx.search( *it ) == -1 ) return; // something is wrong ! :)
+ /* if some notification comes here, consume these notification metadatas */
+ if ( rx.cap( 2 ) == "action" ){
+ curIdx = lastIdx = rx.cap( 1 ).toInt();
+ while ( curIdx == lastIdx ){
+ ++it;
+ if ( it == end ) break;
+ if ( rx.search( *it ) == -1 ) continue; // something is wrong
+ curIdx = rx.cap( 1 ).toInt();
+ }
+ continue;
+ }
+ curIdx = lastIdx = rx.cap( 1 ).toInt();
+ while ( curIdx == lastIdx ) {
+ if ( rx.cap( 2 ) == "path" )
+ path = ma[ *it ];
+ else if ( rx.cap( 2 ) == "text" )
+ text_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "prop" )
+ prop_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "reptxt" )
+ repos_text_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "repprop" )
+ repos_prop_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "rev" )
+ rev = ma[ *it ].toLong();
+ ++it;
+ if ( it == end )
+ break;
+ if ( rx.search( *it ) == -1 ) break; // something is wrong ! :)
+ curIdx = rx.cap( 1 ).toInt();
+ }
+ slotStatus(path, text_status, prop_status, repos_text_status, repos_prop_status, rev);
+ }
+
+ if ( m_cachedDirEntries )
+ emit statusReady(*m_cachedDirEntries, m_savedCallerData);
+}
+
+void SVNFileInfoProvider::slotStatus( const QString& path,int text_status, int prop_status,int repos_text_status, int repos_prop_status, long int rev) {
+// kdDebug(9036) << "##################################################################################### svn provider : slotstatus"
+// << " path " << path << " text_status " << text_status << " prop_status " << prop_status << " repos_text_status " << repos_text_status
+// << " repos_prop_status " << repos_prop_status << " rev " << rev
+// << endl;
+
+ if ( !m_cachedDirEntries )
+ m_cachedDirEntries = new VCSFileInfoMap;
+
+ QString wRev = QString::number( rev ); //work rev
+ QString rRev = QString::number( rev );// repo rev
+ VCSFileInfo::FileState state = VCSFileInfo::Unknown;
+
+ switch ( text_status ) {
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ state = VCSFileInfo::Uptodate;
+ break;
+ case 4:
+ state = VCSFileInfo::Added;
+ break;
+ case 5:
+ break;
+ case 6: //deleted
+ state = VCSFileInfo::Deleted;
+ break;
+ case 7: //replaced
+ state = VCSFileInfo::Replaced;
+ break;
+ case 8: //modified
+ state = VCSFileInfo::Modified;
+ break;
+ case 9: //merged
+ break;
+ case 10: //conflicted
+ state = VCSFileInfo::Conflict;
+ break;
+ case 11: //ignored
+ break;
+ case 12: //obstructed
+ break;
+ case 13: //external
+ break;
+ case 14: //incomplete
+ break;
+ }
+ switch( prop_status ) {
+ case 8:
+ state = VCSFileInfo::Modified;
+ break;
+ }
+ switch ( repos_text_status ) {
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ case 4:
+ break;
+ case 5:
+ break;
+ case 6: //deleted
+ break;
+ case 7: //replaced
+ break;
+ case 8: //modified
+ state = VCSFileInfo::NeedsPatch;
+ break;
+ case 9: //merged
+ break;
+ case 10: //conflicted
+ break;
+ case 11: //ignored
+ break;
+ case 12: //obstructed
+ break;
+ case 13: //external
+ break;
+ case 14: //incomplete
+ break;
+ }
+
+ VCSFileInfo info(QFileInfo( path ).fileName(),wRev,rRev,state);
+ kdDebug(9036) << "Inserting " << info.toString() << endl;
+ m_cachedDirEntries->insert( QFileInfo( path ).fileName(), info);
+}
+
+QString SVNFileInfoProvider::projectDirectory() const {
+ return owner()->project()->projectDirectory();
+}
+
+const VCSFileInfoMap *SVNFileInfoProvider::statusExt( const QString &dirPath,
+ bool checkRepos, bool fullRecurse, bool getAll, bool noIgnore )
+{
+ if ( !m_recursiveDirEntries )
+ m_recursiveDirEntries = new VCSFileInfoMap;
+
+// if ( dirPath != m_recursivePreviousDirPath ) {
+ m_recursiveDirEntries->clear();
+ m_recursivePreviousDirPath = dirPath;
+ KURL servURL = "kdevsvn+http://fakeserver_this_is_normal_behavior/";
+ QByteArray parms;
+ QDataStream s( parms, IO_WriteOnly );
+ int cmd = 109;
+ QString rPath = projectDirectory( );
+ rPath += QDir::separator() + dirPath;
+ kdDebug(9036) << "DIR : " << rPath << " " << KURL( QFileInfo( rPath ).absFilePath() ) << endl;
+ s << cmd << checkRepos << fullRecurse << getAll << noIgnore << -1 << "WORKING" << KURL( QFileInfo( rPath ).absFilePath() );
+ KIO::SimpleJob *job2 = KIO::special(servURL, parms, false);
+ job2->setWindow( m_part->mainWindow()->main() );
+
+
+ QMap<QString,QString> ma;
+ KIO::NetAccess::synchronousRun(job2, m_part->mainWindow()->main(), 0, 0, &ma );
+
+ QValueList<QString> keys = ma.keys();
+ qHeapSort( keys );
+ QValueList<QString>::Iterator begin = keys.begin(), end = keys.end(), it;
+
+ QString path;
+ int text_status = 0, prop_status = 0, repos_text_status = 0, repos_prop_status = 0;
+ long int rev = 0;
+ int curIdx, lastIdx;
+
+ QRegExp rx( "([0-9]*)(.*)" );
+ for ( it = begin; it != end; ) {
+ kdDebug(9036) << "METADATA : " << *it << ":" << ma[ *it ] << endl;
+ if ( rx.search( *it ) == -1 ) return m_recursiveDirEntries; // something is wrong ! :)
+ /* if some notification comes here, consume these notification metadatas */
+ if ( rx.cap( 2 ) == "action" ){
+ curIdx = lastIdx = rx.cap( 1 ).toInt();
+ while ( curIdx == lastIdx ){
+ ++it;
+ if ( it == end ) break;
+ if ( rx.search( *it ) == -1 ) continue; // something is wrong
+ curIdx = rx.cap( 1 ).toInt();
+ }
+ continue;
+ }
+ /* get properties */
+ curIdx = lastIdx = rx.cap( 1 ).toInt();
+ while ( curIdx == lastIdx ) {
+ if ( rx.cap( 2 ) == "path" )
+ path = ma[ *it ];
+ else if ( rx.cap( 2 ) == "text" )
+ text_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "prop" )
+ prop_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "reptxt" )
+ repos_text_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "repprop" )
+ repos_prop_status = ma[ *it ].toInt();
+ else if ( rx.cap( 2 ) == "rev" )
+ rev = ma[ *it ].toLong();
+ ++it;
+ if ( it == end )
+ break;
+ if ( rx.search( *it ) == -1 ) break; // something is wrong ! :)
+ curIdx = rx.cap( 1 ).toInt();
+ }
+ slotStatusExt(dirPath, path, text_status, prop_status, repos_text_status, repos_prop_status, rev);
+ }
+// }
+
+ return m_recursiveDirEntries;
+}
+
+void SVNFileInfoProvider::slotStatusExt(
+ const QString& reqPath, const QString& path,int text_status, int prop_status,int repos_text_status, int repos_prop_status, long int rev)
+{
+
+ if ( !m_recursiveDirEntries )
+ m_recursiveDirEntries = new VCSFileInfoMap;
+
+ QString wRev = QString::number( rev ); //work rev
+ QString rRev = QString::number( rev );// repo rev
+ VCSFileInfo::FileState state = VCSFileInfo::Unknown;
+
+ switch ( text_status ) {
+ case 1: // does not exist
+ break;
+ case 2: // unversioned
+ break;
+ case 3:
+ state = VCSFileInfo::Uptodate;
+ break;
+ case 4:
+ state = VCSFileInfo::Added;
+ break;
+ case 5: // missing
+ break;
+ case 6: //deleted
+ state = VCSFileInfo::Deleted;
+ break;
+ case 7: //replaced
+ state = VCSFileInfo::Replaced;
+ break;
+ case 8: //modified
+ state = VCSFileInfo::Modified;
+ break;
+ case 9: //merged
+ break;
+ case 10: //conflicted
+ state = VCSFileInfo::Conflict;
+ break;
+ case 11: //ignored
+ break;
+ case 12: //obstructed
+ break;
+ case 13: //external
+ break;
+ case 14: //incomplete
+ break;
+ }
+ switch( prop_status ) {
+ case 8:
+ state = VCSFileInfo::Modified;
+ break;
+ }
+ switch ( repos_text_status ) {
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ case 4:
+ break;
+ case 5:
+ break;
+ case 6: //deleted
+ break;
+ case 7: //replaced
+ break;
+ case 8: //modified
+ state = VCSFileInfo::NeedsPatch;
+ break;
+ case 9: //merged
+ break;
+ case 10: //conflicted
+ break;
+ case 11: //ignored
+ break;
+ case 12: //obstructed
+ break;
+ case 13: //external
+ break;
+ case 14: //incomplete
+ break;
+ }
+
+ QString relativeReqPath;
+ if (reqPath == "./"){
+ // case of project top directory
+ QString reqAbsPath = projectDirectory();
+
+ if( path == reqAbsPath ){
+ //key of VCSInfo is project directory itself. So it is set to .
+ relativeReqPath = ".";
+ }
+ else{
+ relativeReqPath = path.right( path.length() - reqAbsPath.length() - 1 );
+ }
+ }
+ else {
+ QString reqAbsPath = projectDirectory() + QDir::separator() + reqPath;
+ relativeReqPath = path.right( path.length() - reqAbsPath.length() - 1 );
+
+ if (relativeReqPath == reqAbsPath){
+ // case of requested directory itself.
+ relativeReqPath = ".";
+ }
+ }
+
+ VCSFileInfo info(relativeReqPath, wRev, rRev, state);
+ m_recursiveDirEntries->insert( relativeReqPath, info );
+
+// VCSFileInfo info(QFileInfo( path ).fileName(),wRev,rRev,state);
+ kdDebug(9036) << "Inserting " << info.toString() << endl;
+// m_recursiveDirEntries->insert( QFileInfo( path ).fileName(), info);
+}
+
+#include "subversion_fileinfo.moc"
+
diff --git a/vcs/subversion/subversion_fileinfo.h b/vcs/subversion/subversion_fileinfo.h
new file mode 100644
index 00000000..e2ab1b70
--- /dev/null
+++ b/vcs/subversion/subversion_fileinfo.h
@@ -0,0 +1,73 @@
+/**
+
+ Copyright (C) 2004-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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SVNFILEINFOPROVIDER_H
+#define SVNFILEINFOPROVIDER_H
+
+#include <qmap.h>
+
+#include <kdevversioncontrol.h>
+#include <kio/job.h>
+#include <dcopclient.h>
+#include <dcopobject.h>
+#include <subversion_part.h>
+
+/**
+Provider for SVN file information
+
+@author Mickael Marchand
+*/
+class SVNFileInfoProvider : public KDevVCSFileInfoProvider, public DCOPObject/*, virtual public DCOPClient*/
+{
+ Q_OBJECT
+ K_DCOP
+
+public:
+ SVNFileInfoProvider( subversionPart *parent, const char *name = 0);
+ virtual ~SVNFileInfoProvider();
+
+// -- Sync interface
+ virtual const VCSFileInfoMap *status( const QString &dirPath );
+// -- These two are used for subversionPart and subversionCore. Of couruse, others can use it.
+ const VCSFileInfoMap* statusExt( const QString &dirPath, bool checkRepos, bool fullRecurse, bool getAll, bool noIgnore );
+ void slotStatusExt( const QString&, const QString& , int, int, int, int, long int ) ;
+
+// -- Async interface for requesting data
+ virtual bool requestStatus( const QString &dirPath, void *callerData, bool recursive = true, bool checkRepos = true );
+
+ QString projectDirectory() const;
+
+k_dcop:
+ void slotStatus( const QString& , int, int, int, int, long int ) ;
+
+public slots:
+ void slotResult( KIO::Job * );
+
+private:
+ mutable void *m_savedCallerData;
+ mutable QString m_previousDirPath;
+ mutable QString m_recursivePreviousDirPath;
+ mutable VCSFileInfoMap *m_cachedDirEntries;
+ mutable VCSFileInfoMap *m_recursiveDirEntries;
+ KIO::SimpleJob *job;
+ subversionPart *m_part;
+};
+
+#endif
diff --git a/vcs/subversion/subversion_global.h b/vcs/subversion/subversion_global.h
new file mode 100644
index 00000000..062d7fe9
--- /dev/null
+++ b/vcs/subversion/subversion_global.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library General Public License for more details.
+ */
+
+#ifndef SUBVERSION_GLOBAL_H
+#define SUBVERSION_GLOBAL_H
+
+#include <kurl.h>
+#include <qdatetime.h>
+
+namespace SvnGlobal
+{
+
+typedef enum {
+ path_to_reposit = 0,
+ path_to_path = 1,
+ dont_touch = 2
+} UrlMode;
+
+/// A structure which describes various system-generated metadata about
+/// a working-copy path or URL.
+class SvnInfoHolder {
+public:
+ // the requested path
+ KURL path;
+ /* Where the item lives in the repository. */
+ KURL url;
+ // The revision of the object. If path_or_url is a working-copy
+ // path, then this is its current working revnum. If path_or_url
+ // is a URL, then this is the repos revision that path_or_url lives in. */
+ int rev;
+ int kind;
+ /* The root URL of the repository. */
+ KURL reposRootUrl;
+ QString reposUuid;
+};
+
+class SvnRevision{
+public:
+ int revNum;
+ QString revKind;
+ QDateTime revDate;
+};
+
+} // end of namespace SvnGlobal
+#endif
diff --git a/vcs/subversion/subversion_part.cpp b/vcs/subversion/subversion_part.cpp
new file mode 100644
index 00000000..f918ea44
--- /dev/null
+++ b/vcs/subversion/subversion_part.cpp
@@ -0,0 +1,569 @@
+/**
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+#include "subversion_part.h"
+
+#include <qwhatsthis.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kdevgenericfactory.h>
+#include <kaction.h>
+#include <kpopupmenu.h>
+
+#include "kdevcore.h"
+#include "kdevmainwindow.h"
+#include "subversion_core.h"
+#include "subversion_widget.h"
+#include "subversionprojectwidget.h"
+#include "subversion_fileinfo.h"
+#include "subversion_global.h"
+#include "kdevversioncontrol.h"
+#include "svn_fileselectdlg_commit.h"
+#include "svn_logviewwidget.h"
+#include "svn_switchwidget.h"
+#include "svn_copywidget.h"
+#include "svn_mergewidget.h"
+
+#include "urlutil.h"
+#include <qvbox.h>
+#include <kdialogbase.h>
+#include <kparts/part.h>
+#include <kdevpartcontroller.h>
+#include <kdevproject.h>
+#include <domutil.h>
+#include <kurlrequester.h>
+#include <qradiobutton.h>
+#include <kdebug.h>
+#include <qwidget.h>
+#include <kdevplugininfo.h>
+
+#include <kmessagebox.h>
+
+using namespace SvnGlobal;
+
+static const KDevPluginInfo data("kdevsubversion");
+
+typedef KDevGenericFactory<subversionPart> subversionFactory;
+K_EXPORT_COMPONENT_FACTORY( libkdevsubversion, subversionFactory( data ) )
+
+//bool g_projectWasJustCreated = false;
+
+subversionPart::subversionPart(QObject *parent, const char *name, const QStringList& )
+ : KDevVersionControl(&data, parent, name ? name : "Subversion" ) {
+ setInstance(subversionFactory::instance());
+ m_projWidget = 0;
+
+ m_impl = new subversionCore( this );
+
+ //m_impl->processWidget()->setIcon( SmallIcon("db") );
+
+ setupActions();
+
+ connect( m_impl, SIGNAL(checkoutFinished(QString)), SIGNAL(finishedFetching(QString)) );
+
+ // Context menu
+ connect( core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), this, SLOT(contextMenu(QPopupMenu *, const Context *)) );
+ connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(projectConfigWidget(KDialogBase*)) );
+ connect( core(), SIGNAL(stopButtonClicked(KDevPlugin*)), this, SLOT(slotStopButtonClicked(KDevPlugin*)) );
+ connect( core(), SIGNAL(projectOpened()), this, SLOT(slotProjectOpened()) );
+ connect( core(), SIGNAL(projectClosed()), this, SLOT(slotProjectClosed()) );
+
+ m_impl->processWidget()->setCaption(i18n( "Subversion Output" ));
+ mainWindow()->embedOutputView( (QWidget*)m_impl->processWidget(), i18n( "Subversion" ), i18n( "Subversion messages" ) );
+ QWhatsThis::add((QWidget*)m_impl->processWidget(), i18n("<b>Subversion</b><p>Subversion operations window."));
+
+}
+
+subversionPart::~subversionPart() {
+ if ( m_projWidget ){
+ delete (subversionProjectWidget*) m_projWidget;
+ m_projWidget = 0;
+ }
+ delete m_impl;
+}
+
+void subversionPart::setupActions() {
+ actionCommit = new KAction( i18n("&Commit to Repository..."), 0, this, SLOT(slotActionCommit()), actionCollection(), "subversion_commit" );
+ actionCommit->setToolTip( i18n("Commit file(s)") );
+ actionCommit->setWhatsThis( i18n("<b>Commit file(s)</b><p>Commits file to repository if modified.") );
+
+ /* actionDiff = new KAction( i18n("&Difference Between Revisions"), 0, this, SLOT(slotActionDiff()),
+ actionCollection(), "subversion_diff" );
+ actionDiff->setToolTip( i18n("Build difference") );
+ actionDiff->setWhatsThis( i18n("<b>Build difference</b><p>Builds difference between releases.") );
+ */
+ actionAdd = new KAction( i18n("&Add to Repository"), 0, this, SLOT(slotActionAdd()), actionCollection(), "subversion_add" );
+ actionAdd->setToolTip( i18n("Add file to repository") );
+ actionAdd->setWhatsThis( i18n("<b>Add file to repository</b><p>Adds file to repository.") );
+
+ actionLog = new KAction( i18n("Show logs..."), 0, this, SLOT(slotLog()), actionCollection(), "subversion_log" );
+ actionBlame = new KAction( i18n("Blame..."), 0, this, SLOT(slotBlame()), actionCollection(), "subversion_blame");
+
+ actionRemove = new KAction( i18n("&Remove From Repository"), 0, this, SLOT(slotActionDel()), actionCollection(), "subversion_remove" );
+ actionRemove->setToolTip( i18n("Remove from repository") );
+ actionRemove->setWhatsThis( i18n("<b>Remove from repository</b><p>Removes file(s) from repository.") );
+
+ actionUpdate = new KAction( i18n("&Update"), 0, this, SLOT(slotActionUpdate()), actionCollection(), "subversion_update" );
+ actionUpdate->setToolTip( i18n("Update") );
+ actionUpdate->setWhatsThis( i18n("<b>Update</b><p>Updates file(s) from repository.") );
+
+ actionDiffLocal = new KAction( i18n("&Diff to BASE"), 0, this, SLOT(slotActionDiffLocal()), actionCollection(), "subversion_diff_local" );
+ actionDiffLocal->setToolTip( i18n("Diff to BASE") );
+ actionDiffLocal->setWhatsThis( i18n("<b>Diff to disk</b><p>Diff current file to the BASE checked out copy.") );
+
+ actionDiffHead = new KAction( i18n("&Diff to HEAD"), 0, this, SLOT(slotActionDiffLocal()), actionCollection(), "subversion_diff_head" );
+ actionDiffHead->setToolTip( i18n("Diff to HEAD") );
+ actionDiffHead->setWhatsThis( i18n("<b>Diff HEAD</b><p>Diff the current file to HEAD in svn.") );
+
+
+ actionRevert = new KAction( i18n("&Revert"), 0, this, SLOT(slotActionRevert()), actionCollection(), "subversion_revert" );
+ actionRevert->setToolTip( i18n("Revert") );
+ actionRevert->setWhatsThis( i18n("<b>Revert</b><p>Undo local changes.") );
+
+ /*
+ actionAddToIgnoreList = new KAction( i18n("&Ignore in Subversion Operations"), 0,
+ this, SLOT(slotActionAddToIgnoreList()), actionCollection(), "subversion_ignore" );
+ actionAddToIgnoreList->setToolTip( i18n("Ignore in Subversion operations") );
+ actionAddToIgnoreList->setWhatsThis( i18n("<b>Ignore in Subversion operations</b><p>Ignores file(s).") );
+
+ actionRemoveFromIgnoreList = new KAction( i18n("Do &Not Ignore in Subversion Operations"), 0,
+ this, SLOT(slotActionRemoveFromIgnoreList()), actionCollection(), "subversion_donot_ignore" );
+ actionRemoveFromIgnoreList->setToolTip( i18n("Do not ignore in Subversion operations") );
+ actionRemoveFromIgnoreList->setWhatsThis( i18n("<b>Do not ignore in Subversion operations</b><p>Do not ignore file(s).") );
+ */
+ actionResolve = new KAction( i18n("Re&solve Conflicting State"), 0,
+ this, SLOT(slotActionResolve()), actionCollection(), "subversion_resolve" );
+ actionResolve->setToolTip( i18n("Resolve the conflicting state of a file after a merge") );
+ actionResolve->setWhatsThis( i18n("<b>Resolve the conflicting state</b><p>Remove the conflict state that can be set on a file after a merge failed.") );
+ actionSwitch = new KAction( i18n("Switch this working copy to URL.."), 0,
+ this, SLOT(slotSwitch()), actionCollection(), "subversion_switch" );
+ // warn slogCopy(), slotMerge only works on context menu. There is no main-menu action
+ actionCopy = new KAction( i18n("Copy this working copy to URL.."), 0,
+ this, SLOT(slotCopy()), actionCollection(), "subversion_copy" );
+ actionMerge = new KAction( i18n("Merge difference to working copy"), 0,
+ this, SLOT(slotMerge()), actionCollection(), "subversion_merge" );
+}
+
+QWidget* subversionPart::newProjectWidget( QWidget* parent ) {
+ if ( !m_projWidget )
+ m_projWidget = new subversionProjectWidget(parent,"projectwidget");
+ return m_projWidget;
+}
+
+void subversionPart::createNewProject( const QString& dirname ) {
+ if ( !m_projWidget ) return;
+
+ m_impl->createNewProject( dirname, KURL( m_projWidget->importURL->url() ), m_projWidget->yes->isChecked() );
+
+}
+
+bool subversionPart::fetchFromRepository() {
+ m_impl->checkout();
+ return true;
+}
+
+KDevVCSFileInfoProvider * subversionPart::fileInfoProvider() const {
+ return m_impl->fileInfoProvider();
+}
+
+void subversionPart::contextMenu( QPopupMenu *popup, const Context *context ) {
+ //no project, no subversion. Don't test on projectDirectory() here. If the user wants this project to have subversion support
+ //give it to him. e.g. for out of root subprojects like with qmake
+if(!project())
+ return;
+
+ kdDebug(9036) << "contextMenu()" << endl;
+ if (context->hasType( Context::FileContext ) ||
+ context->hasType( Context::EditorContext ))
+ {
+
+ if (context->hasType( Context::FileContext ))
+ {
+ kdDebug(9036) << "Requested for a FileContext" << endl;
+ const FileContext *fcontext = static_cast<const FileContext*>( context );
+ m_urls = fcontext->urls();
+ }
+ else
+ {
+ kdDebug(9036) << "Requested for an EditorContext" << endl;
+ const EditorContext *editorContext = static_cast<const EditorContext*>( context );
+ m_urls = editorContext->url();
+ }
+ // THis stuff should end up into prepareOperation()
+ URLUtil::dump( m_urls );
+ if (m_urls.count() <= 0)
+ return;
+
+ KPopupMenu *subMenu = new KPopupMenu( popup );
+ if (context->hasType( Context::FileContext ))
+ popup->insertSeparator();
+
+ int id = subMenu->insertItem( actionCommit->text(), this, SLOT(slotCommit()) );
+ // CvsService let to do log and diff operations only on one file (or directory) at time
+ /* if (m_urls.count() == 1)
+ {
+ subMenu->insertItem( actionDiff->text(), this, SLOT(slotDiff()) );
+ subMenu->insertItem( actionLog->text(), this, SLOT(slotLog()) );
+ }*/
+ subMenu->setWhatsThis(id, i18n("<b>Commit file(s)</b><p>Commits file to repository if modified."));
+ id = subMenu->insertItem( actionAdd->text(), this, SLOT(slotAdd()) );
+ subMenu->setWhatsThis(id, i18n("<b>Add file to repository</b><p>Adds file to repository."));
+ id = subMenu->insertItem( actionRemove->text(), this, SLOT(slotDel()) );
+ subMenu->setWhatsThis(id, i18n("<b>Remove from repository</b><p>Removes file(s) from repository."));
+ id = subMenu->insertItem( actionLog->text(), this, SLOT(slotLog()) );
+ subMenu->setWhatsThis(id, i18n("<b>Show logs..</b><p>View Logs"));
+ id = subMenu->insertItem( actionBlame->text(), this, SLOT(slotBlame()) );
+ subMenu->setWhatsThis(id, i18n("<b>Blame 0:HEAD </b><p>Show Annotate"));
+
+ subMenu->insertSeparator();
+ id = subMenu->insertItem( actionDiffLocal->text(), this, SLOT(slotDiffLocal()) );
+ subMenu->setWhatsThis(id, i18n("<b>Diff</b><p>Diff file to local disk."));
+
+ id = subMenu->insertItem( actionDiffHead->text(), this, SLOT(slotDiffHead()) );
+ subMenu->setWhatsThis(id, i18n("<b>Diff</b><p>Diff file to repository."));
+
+ id = subMenu->insertItem( actionUpdate->text(), this, SLOT(slotUpdate()) );
+ subMenu->setWhatsThis(id, i18n("<b>Update</b><p>Updates file(s) from repository."));
+ id = subMenu->insertItem( actionRevert->text(), this, SLOT(slotRevert()) );
+ subMenu->setWhatsThis(id, i18n("<b>Revert</b><p>Undo local changes.") );
+ id = subMenu->insertItem( actionResolve->text(), this, SLOT(slotResolve()) );
+ subMenu->setWhatsThis(id, i18n("<b>Resolve</b><p>Resolve conflicting state.") );
+ id = subMenu->insertItem( actionSwitch->text(), this, SLOT(slotSwitch()) );
+ subMenu->setWhatsThis(id, i18n("<b>Switch</b><p>Switch working tree.") );
+ id = subMenu->insertItem( actionCopy->text(), this, SLOT(slotCopy()) );
+ subMenu->setWhatsThis(id, i18n("<b>Copy</b><p>Copy from/between path/URLs") );
+ id = subMenu->insertItem( actionMerge->text(), this, SLOT(slotMerge()) );
+ subMenu->setWhatsThis(id, i18n("<b>Merge</b><p>Merge difference to working copy") );
+
+ /*
+ subMenu->insertSeparator();
+ id = subMenu->insertItem( actionAddToIgnoreList->text(), this, SLOT(slotAddToIgnoreList()) );
+ subMenu->setWhatsThis(id, i18n("<b>Ignore in Subversion operations</b><p>Ignores file(s)."));
+ id = subMenu->insertItem( actionRemoveFromIgnoreList->text(), this, SLOT(slotRemoveFromIgnoreList()) );
+ subMenu->setWhatsThis(id, i18n("<b>Do not ignore in Subversion operations</b><p>Do not ignore file(s)."));
+*/
+ // Now insert in parent menu
+ popup->insertItem( i18n("Subversion"), subMenu );
+ }
+}
+
+bool subversionPart::urlFocusedDocument( KURL &url ) {
+ KParts::ReadOnlyPart *part = dynamic_cast<KParts::ReadOnlyPart*>( partController()->activePart() );
+ if ( part ) {
+ if (part->url().isLocalFile() ) {
+ url = part->url();
+ return true;
+ }
+ }
+ return false;
+}
+
+void subversionPart::slotActionUpdate() {
+ kdDebug(9036) << "subversion: slotActionUpdate()" << endl;
+ KURL doc;
+ if (urlFocusedDocument( doc )) {
+ m_impl->update( doc );
+ }
+}
+
+void subversionPart::slotUpdate() {
+ m_impl->update (m_urls);
+}
+
+void subversionPart::slotActionResolve() {
+ kdDebug(9036) << "subversion: slotActionResolve()" << endl;
+ KURL doc;
+ if (urlFocusedDocument( doc )) {
+ m_impl->resolve( doc );
+ }
+}
+
+void subversionPart::slotResolve() {
+ m_impl->resolve (m_urls);
+}
+
+void subversionPart::slotSwitch()
+{
+ if( m_urls.count() > 1 ){
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("Please select only one item for subversion switch") );
+ return;
+ }
+ if( m_urls.count() < 1 ) return;
+
+ // retrieve repository info from local-copy metadata which will be displayed in dialog box
+ KURL wcPath = m_urls.first();
+ QMap< KURL, SvnGlobal::SvnInfoHolder> holderMap;
+ SvnGlobal::SvnInfoHolder holder;
+
+ m_impl->clientInfo( wcPath, false, holderMap );
+ QValueList< SvnGlobal::SvnInfoHolder > holderList = holderMap.values();
+ holder = holderList.first();
+ // invoke dialog box
+ SvnSwitchDlg dlg( &holder, wcPath.path(), (QWidget*)project()->mainWindow()->main() );
+
+ if( dlg.exec() != QDialog::Accepted ){
+ return;
+ }
+ // check target url's validity
+ KURL repositUrl = KURL( dlg.destUrl() );
+ if( !repositUrl.isValid() ){
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("The destination URL is invalid") );
+ return;
+ }
+ // call core
+ if( dlg.switchOnly() )
+ m_impl->switchTree( wcPath, repositUrl, -1, "HEAD", dlg.recursive() );
+ else if( dlg.relocation() )
+ m_impl->switchRelocate( wcPath, dlg.currentUrl(), repositUrl, dlg.recursive() );
+ else
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("Fail to conduct subversion switch. No action was selected") );
+}
+
+void subversionPart::slotCopy()
+{
+ // error check
+ if( m_urls.count() > 1 ){
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("Please select only one item for subversion switch") );
+ return;
+ }
+ if( m_urls.count() < 1 ) return;
+
+ // retrieve repository info from local-copy metadata which will be displayed in dialog box
+ KURL wcPath = m_urls.first();
+ QMap< KURL, SvnGlobal::SvnInfoHolder> holderMap;
+ SvnGlobal::SvnInfoHolder holder;
+ m_impl->clientInfo( wcPath, false, holderMap );
+ QValueList< SvnGlobal::SvnInfoHolder > holderList = holderMap.values();
+ holder = holderList.first();
+ // start input dialog
+ SvnCopyDialog dlg( wcPath.prettyURL(),
+ &holder,
+ (QWidget*)project()->mainWindow()->main());
+
+ if( dlg.exec() != QDialog::Accepted )
+ return;
+ // retrieve user input
+ KURL srcUrl = dlg.sourceUrl();
+ int rev = dlg.revision();
+ QString revKind = dlg.revKind();
+ KURL dest = dlg.destUrl();
+
+ kdDebug(9036) << " SRC: " << srcUrl << " DEST: " << dest << " Revnum: " << rev << " RevKind: " << revKind << endl;
+
+ m_impl->svnCopy( srcUrl, rev, revKind, dest );
+}
+
+void subversionPart::slotMerge()
+{
+ // error check
+ if( m_urls.count() > 1 ){
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("Please select only one item for subversion merge") );
+ return;
+ }
+ if( m_urls.count() < 1 ) return;
+
+ KURL wcTarget= m_urls.first();
+ SvnMergeDialog dlg( wcTarget, (QWidget*)project()->mainWindow()->main() );
+ if( dlg.exec() != QDialog::Accepted ) return;
+
+ KURL src1 = dlg.source1();
+ SvnRevision rev1 = dlg.rev1();
+ KURL src2 = dlg.source2();
+ SvnRevision rev2 = dlg.rev2();
+
+ m_impl->merge( src1, rev1.revNum, rev1.revKind, src2, rev2.revNum, rev2.revKind, wcTarget,
+ dlg.recurse(), dlg.ignoreAncestry(), dlg.force(), dlg.dryRun() );
+}
+
+void subversionPart::slotActionCommit() {
+ kdDebug(9036) << "subversion: slotActionCommit()" << endl;
+ KURL doc;
+ if (urlFocusedDocument( doc )) {
+ m_impl->commit( doc, true, true );
+ }
+}
+
+void subversionPart::slotActionAdd() {
+ kdDebug(9036) << "subversion: slotActionAdd()" << endl;
+ KURL doc;
+ if (urlFocusedDocument( doc )) {
+ m_impl->add( doc );
+ }
+}
+
+void subversionPart::slotActionDel() {
+ kdDebug(9036) << "subversion: slotActionDel()" << endl;
+ KURL doc;
+ if (urlFocusedDocument( doc )) {
+ m_impl->del( doc );
+ }
+}
+
+void subversionPart::slotActionRevert() {
+ kdDebug(9036) << "subversion: slotActionRevert()" << endl;
+ KURL doc;
+ if (urlFocusedDocument( doc )) {
+ m_impl->revert( doc );
+ }
+}
+
+void subversionPart::slotActionDiffLocal() {
+ kdDebug(9036) << "subversion: slotActionDiffLocal()" << endl;
+ KURL doc;
+ if (urlFocusedDocument( doc )) {
+ m_impl->diff( doc, "BASE" );
+ }
+}
+void subversionPart::slotActionDiffHead() {
+ kdDebug(9036) << "subversion: slotActionDiffHead()" << endl;
+ KURL doc;
+ if (urlFocusedDocument( doc )) {
+ m_impl->diff( doc, "HEAD" );
+ }
+}
+void subversionPart::slotCommit()
+{
+ SVNFileSelectDlgCommit dialog( m_urls, this, 0 );
+ if( dialog.exec() == QDialog::Accepted ){
+ KURL::List tobeCommittedUrls = dialog.checkedUrls();
+ bool recursive = dialog.recursive();
+ bool keepLocks = dialog.keepLocks();
+ m_impl->commit(tobeCommittedUrls, recursive, keepLocks );
+ }
+}
+void subversionPart::slotAdd() {
+ m_impl->add( m_urls );
+}
+
+void subversionPart::slotLog()
+{
+ if (m_urls.count() > 1){
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("Please select only one item for subversion log") );
+ return;
+ }
+ SvnLogViewOptionDlg dlg;
+ if( dlg.exec() ){
+ int revstart = dlg.revstart();
+ QString revkindstart = dlg.revKindStart();
+ int revend = dlg.revend();
+ QString revkindend = dlg.revKindEnd();
+ bool strictNode = dlg.strictNode();
+ m_impl->svnLog (m_urls, revstart, revkindstart, revend, revkindend, true/*changedPath*/, strictNode);
+ } else{
+ return;
+ }
+}
+void subversionPart::slotBlame()
+{
+ if (m_urls.count() > 1){
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("Please select only one item to see annotate") );
+ return;
+ }
+ if (m_urls.count() < 1){
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("Select file to see blame") );
+ return;
+ }
+ KURL url = m_urls.first();
+ m_impl->blame(url, SvnGlobal::path_to_reposit, 0, "", -1, "BASE");
+}
+
+void subversionPart::slotDel() {
+ m_impl->del (m_urls);
+}
+
+// note: currently diffAsync does not support merging. But svncore::diff()
+// cannot be invoked on directory, while diffAsync can.
+void subversionPart::slotDiffLocal() {
+// m_impl->diff (m_urls, "BASE");
+ if( m_urls.count() < 1 ){
+ // Impossible to reach here but..
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("Select file or directory to see diff") );
+ return;
+ }
+ m_impl->diffAsync( *(m_urls.begin()), *(m_urls.begin()), -1, "BASE", -1, "WORKING", true );
+}
+void subversionPart::slotDiffHead() {
+// m_impl->diff (m_urls, "HEAD");
+ if( m_urls.count() < 1 ){
+ // Impossible to reach here but..
+ KMessageBox::error( (QWidget*)project()->mainWindow()->main(),
+ i18n("Select file or directory to see diff") );
+ return;
+ }
+ m_impl->diffAsync( *(m_urls.begin()), *(m_urls.begin()), -1, "WORKING", -1, "HEAD", true );
+}
+
+void subversionPart::slotRevert() {
+ m_impl->revert (m_urls);
+}
+
+void subversionPart::slotProjectOpened() {
+ kdDebug(9036) << "subversion :projectOpened" << endl;
+/* if ( g_projectWasJustCreated ) {
+ //saveOptions();
+ g_projectWasJustCreated = false;
+ } */
+ //loadOptions();
+ /// \FIXME slots
+ //connect( project(), SIGNAL(addedFilesToProject(const QStringList&)), this, SLOT(slotAddFilesToProject(const QStringList &)) );
+ //connect( project(), SIGNAL(removedFilesFromProject(const QStringList&)), this, SLOT(slotRemovedFilesFromProject(const QStringList &)) );
+}
+
+void subversionPart::slotProjectClosed() {
+ kdDebug(9036) << "subversion :projectClosed" << endl;
+ //saveOptions();
+ /// \FIXME slots
+ //disconnect( project(), SIGNAL(addedFilesToProject(const QStringList&)), this, SLOT(slotAddFilesToProject(const QStringList &)) );
+ //disconnect( project(), SIGNAL(removedFilesFromProject(const QStringList&)), this, SLOT(slotRemovedFilesFromProject(const QStringList &)) );
+}
+
+void subversionPart::savePartialProjectSession(QDomElement* dom) {
+ kdDebug(9036) << "subversion : savePartialProjectSession" << endl;
+ QDomDocument doc = dom->ownerDocument();
+ QDomElement svn = doc.createElement( "subversion" );
+ svn.setAttribute( "base", base.url() );
+ dom->appendChild( svn );
+}
+
+void subversionPart::restorePartialProjectSession(const QDomElement* dom) {
+ kdDebug(9036) << "subversion : restorePartialProjectSession" << endl;
+ QDomElement svn = dom->namedItem("subversion").toElement();
+ base = svn.attribute( "base", "" );
+}
+
+bool subversionPart::isValidDirectory( const QString &dirPath) const {
+ QString svn = "/.svn/";
+ QDir svndir( dirPath + svn );
+ QString entriesFileName = dirPath + svn + "entries";
+
+ kdDebug(9036) << "dirpath " << dirPath+"/.svn/" << " exists:" << svndir.exists() << endl;
+ kdDebug(9036) << "entries " << entriesFileName << " exists:" << QFile::exists( entriesFileName ) << endl;
+ return svndir.exists() &&
+ QFile::exists( entriesFileName );
+}
+
+#include "subversion_part.moc"
diff --git a/vcs/subversion/subversion_part.h b/vcs/subversion/subversion_part.h
new file mode 100644
index 00000000..911f8f7e
--- /dev/null
+++ b/vcs/subversion/subversion_part.h
@@ -0,0 +1,119 @@
+/* Copyright (C) 2003
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+#ifndef __KDEVPART_SUBVERSION_H__
+#define __KDEVPART_SUBVERSION_H__
+
+
+#include <qguardedptr.h>
+#include <kdevplugin.h>
+#include <kurl.h>
+#include <qpopupmenu.h>
+#include <kdialogbase.h>
+#include "kdevversioncontrol.h"
+
+class subversionCore;
+class subversionOptionsWidget;
+class subversionProjectWidget;
+class Context;
+namespace SvnGlobal
+{
+class SvnInfoHolder;
+};
+
+class subversionPart : public KDevVersionControl
+{
+ Q_OBJECT
+
+public:
+ subversionPart(QObject *parent, const char *name, const QStringList &);
+ virtual ~subversionPart();
+
+ void setupActions();
+ QWidget* newProjectWidget( QWidget* parent );
+ void createNewProject( const QString& dirname );
+ bool fetchFromRepository();
+ KDevVCSFileInfoProvider * fileInfoProvider() const;
+ bool urlFocusedDocument( KURL &url );
+ void restorePartialProjectSession(const QDomElement* );
+ void savePartialProjectSession(QDomElement* );
+ void setBaseURL(const KURL& url ) { base = url; }
+ KURL baseURL() { return base; }
+ virtual bool isValidDirectory( const QString &dirPath ) const;
+ KURL::List urls() { return m_urls; }
+ subversionCore* svncore() { return m_impl; }
+
+signals:
+// void finishedFetching( QString destinationDir );
+
+private slots:
+ void contextMenu( QPopupMenu *popup, const Context *context );
+ void slotActionUpdate();
+ void slotActionRevert();
+ void slotActionCommit();
+ void slotActionAdd();
+ void slotActionDel();
+ void slotActionDiffHead();
+ void slotActionDiffLocal();
+ void slotActionResolve();
+ void slotUpdate();
+ void slotRevert();
+ void slotCommit();
+ void slotAdd();
+ void slotDel();
+ void slotLog();
+ void slotBlame();
+ void slotDiffLocal();
+ void slotDiffHead();
+ void slotResolve();
+ void slotSwitch();
+ void slotCopy();
+ void slotMerge();
+ void slotProjectClosed();
+ void slotProjectOpened();
+
+private:
+ QGuardedPtr<subversionCore> m_impl;
+ KURL::List m_urls;
+
+ KAction *actionCommit,
+ *actionDiffHead,
+ *actionDiffLocal,
+ *actionAdd,
+ *actionLog,
+ *actionBlame,
+ *actionRemove,
+ *actionUpdate,
+ //*actionAddToIgnoreList,
+ //*actionRemoveFromIgnoreList,
+ *actionRevert,
+ *actionResolve,
+ *actionSwitch,
+ *actionCopy,
+ *actionMerge;
+
+ QGuardedPtr<subversionProjectWidget> m_projWidget;
+ KURL base;
+
+public:
+ QMap< KURL, SvnGlobal::SvnInfoHolder > m_prjInfoMap;
+
+};
+
+
+#endif
diff --git a/vcs/subversion/subversion_widget.cpp b/vcs/subversion/subversion_widget.cpp
new file mode 100644
index 00000000..af1ca14f
--- /dev/null
+++ b/vcs/subversion/subversion_widget.cpp
@@ -0,0 +1,136 @@
+/**
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+#include <kparts/part.h>
+#include <kdevcore.h>
+#include <kdebug.h>
+#include <klineedit.h>
+
+#include "subversion_part.h"
+#include "subversion_widget.h"
+#include <ktextedit.h>
+#include <klocale.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+
+subversionWidget::subversionWidget( subversionPart *part, QWidget *parent, const char* name )
+ : KTabWidget(parent)
+{
+ m_part = part;
+ m_edit = new KTextEdit( this );
+ m_edit->setReadOnly( TRUE );
+ tab()->addTab( m_edit, i18n("Notification") );
+ m_closeButton = new QPushButton( tab() );
+ m_closeButton->setText( i18n("Close") );
+ tab()->setCornerWidget(m_closeButton);
+ connect( m_closeButton, SIGNAL(clicked()), this, SLOT(closeCurrentTab()) );
+}
+
+subversionWidget::~subversionWidget()
+{}
+
+void subversionWidget::append( QString notifications )
+{
+ if( !m_edit ){
+ // should not happen
+ m_edit = new KTextEdit(this);
+ }
+ m_edit->append( notifications );
+ showPage( m_edit );
+}
+
+void subversionWidget::showLogResult( QValueList<SvnLogHolder> *holderList, QString reqUrl )
+{
+ SvnLogViewWidget *widget = new SvnLogViewWidget( m_part, this );
+ widget->setLogResult( holderList );
+ widget->setRequestedUrl( reqUrl );
+ tab()->addTab( widget, i18n("Log History") );
+ tab()->setTabEnabled( widget, true );
+ tab()->showPage( widget );
+}
+
+void subversionWidget::showBlameResult( QValueList<SvnBlameHolder> *blamelist )
+{
+ SvnBlameWidget *widget = new SvnBlameWidget( this );
+ widget->copyBlameData( blamelist );
+ tab()->addTab( widget, i18n("Blame") );
+ tab()->setTabEnabled( widget, true );
+ tab()->showPage( widget );
+}
+void subversionWidget::closeCurrentTab()
+{
+ QWidget *current = tab()->currentPage();
+ KTextEdit *edit = static_cast<KTextEdit*>(current);
+ if( edit ){
+ if( edit == m_edit ) // main notification output should not be deleted
+ return;
+ }
+ tab()->removePage( current );
+ delete current;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+SvnIntSortListItem::SvnIntSortListItem( QListView* parent )
+ :QListViewItem(parent)
+{}
+SvnIntSortListItem::~SvnIntSortListItem()
+{}
+
+int SvnIntSortListItem::compare( QListViewItem *item, int col, bool ascending ) const
+{
+
+ unsigned int myVal = this->text(col).toUInt();
+ unsigned int yourVal = item->text(col).toUInt();
+ if( myVal < yourVal ) return -1;
+ if( myVal > yourVal ) return 1;
+ return 0;
+}
+
+SvnLogViewItem::SvnLogViewItem( QListView * parent )
+ :SvnIntSortListItem( parent )
+{
+ m_pathList = "";
+ m_message = "";
+}
+SvnLogViewItem ::~SvnLogViewItem ()
+{}
+
+////////////////////////////////////////////////////////////////////////
+
+SvnProgressDlg::SvnProgressDlg( bool showNow )
+ : KIO::DefaultProgress( showNow )
+{
+ setStopOnClose( true );
+ setCaption( i18n("Subversion Job Progress") );
+}
+
+SvnProgressDlg::~SvnProgressDlg()
+{}
+
+void SvnProgressDlg::setSourceUrl( const QString &src )
+{
+ sourceEdit->setText( src );
+}
+void SvnProgressDlg::setDestUrl( const QString &dest )
+{
+ destEdit->setText( dest );
+}
+
+#include "subversion_widget.moc"
diff --git a/vcs/subversion/subversion_widget.h b/vcs/subversion/subversion_widget.h
new file mode 100644
index 00000000..4a21b636
--- /dev/null
+++ b/vcs/subversion/subversion_widget.h
@@ -0,0 +1,95 @@
+/* Copyright (C) 2003
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SUBVERSION_WIDGET_H__
+#define __SUBVERSION_WIDGET_H__
+
+#include <qlistview.h>
+#include "svn_blamewidget.h"
+#include "svn_logviewwidget.h"
+#include <qvaluelist.h>
+
+class subversionPart;
+#include <ktabwidget.h>
+#include <kio/defaultprogress.h>
+#include <qguardedptr.h>
+class KTextEdit;
+class SvnLogHolder;
+class SvnBlameHolder;
+class SvnLogViewWidget;
+class QToolButton;
+class QPushButton;
+
+/** The main Subversion DockWidget. Contains logview-output, blame-output, status and etc */
+// class subversionWidget : public SvnOutputWidgetBase
+class subversionWidget : public KTabWidget
+{
+ Q_OBJECT
+public:
+ subversionWidget(subversionPart *part, QWidget *parent, const char* name);
+ ~subversionWidget();
+
+ // append what?. Append any text status outputs
+ void append( QString notifications );
+ void showLogResult( QValueList<SvnLogHolder> *holderList, QString reqUrl );
+ void showBlameResult( QValueList<SvnBlameHolder> *blamelist );
+
+protected slots:
+ void closeCurrentTab();
+
+private:
+ KTabWidget* tab(){ return this; }
+ subversionPart *m_part;
+
+ QGuardedPtr<KTextEdit> m_edit;
+ QPushButton *m_closeButton;
+
+};
+/**
+ * reimplement compare(), to be able to sort any item by integer
+ */
+class SvnIntSortListItem : public QListViewItem {
+public:
+ SvnIntSortListItem ( QListView* parent=0 );
+ ~SvnIntSortListItem ();
+ /** Returns < 0 if this item is less than i, 0 if they are equal and > 0 if this item is greater than i.
+ */
+ virtual int compare( QListViewItem* i, int col, bool ascending ) const;
+};
+
+class SvnLogViewItem : public SvnIntSortListItem {
+ public:
+ SvnLogViewItem( QListView* parent );
+ ~SvnLogViewItem();
+
+ QString m_pathList;
+ QString m_message;
+};
+
+/////////////////////////////////////////////////////////////
+/// Subversion Progress Display Widget
+class SvnProgressDlg : public KIO::DefaultProgress {
+public:
+ SvnProgressDlg( bool showNow = true );
+ ~SvnProgressDlg();
+ void setSourceUrl( const QString & );
+ void setDestUrl( const QString & );
+};
+
+#endif
diff --git a/vcs/subversion/subversiondiff.ui b/vcs/subversion/subversiondiff.ui
new file mode 100644
index 00000000..dab4ca0e
--- /dev/null
+++ b/vcs/subversion/subversiondiff.ui
@@ -0,0 +1,100 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Subversion_Diff</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>Subversion_Diff</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>511</width>
+ <height>282</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Subversion Diff</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTextBrowser">
+ <property name="name">
+ <cstring>text</cstring>
+ </property>
+ <property name="textFormat">
+ <enum>PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <enum>NoWrap</enum>
+ </property>
+ <property name="autoFormatting">
+ <set>AutoAll</set>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonOk</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>Subversion_Diff</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/vcs/subversion/subversionprojectwidget.ui b/vcs/subversion/subversionprojectwidget.ui
new file mode 100644
index 00000000..3977ce4c
--- /dev/null
+++ b/vcs/subversion/subversionprojectwidget.ui
@@ -0,0 +1,89 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>subversionProjectWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>subversionProjectWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>438</width>
+ <height>149</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>New Subversion Project</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Import address:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>importURL</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>importURL</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>init</cstring>
+ </property>
+ <property name="title">
+ <string>Create &amp;Standard Directories (tags/trunk/branches/)?</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>yes</cstring>
+ </property>
+ <property name="text">
+ <string>Yes</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>no</cstring>
+ </property>
+ <property name="text">
+ <string>No</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/vcs/subversion/svn_blamewidget.cpp b/vcs/subversion/svn_blamewidget.cpp
new file mode 100644
index 00000000..5d186177
--- /dev/null
+++ b/vcs/subversion/svn_blamewidget.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library General Public License for more details.
+ */
+
+#include "svn_blamewidget.h"
+#include "subversion_widget.h"
+#include <qmap.h>
+#include <qlistview.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qstringlist.h>
+#include <qfont.h>
+
+#include <klocale.h>
+#include <kmessagebox.h>
+
+SvnBlameWidget::SvnBlameWidget( QWidget *parent, const char* name, bool modal, WFlags f )
+ :QWidget( parent )
+{
+ m_layout = new QVBoxLayout( this, 1, 1 );
+ m_layout->setMargin(1);
+
+ m_listView = new QListView( this );
+ outView()->setAllColumnsShowFocus( TRUE );
+ outView()->addColumn( i18n("Line") );
+ outView()->addColumn( i18n("Rev") );
+ outView()->addColumn( i18n("Date") );
+ outView()->addColumn( i18n("Author") );
+ outView()->addColumn( i18n("Content") );
+
+ m_layout->addWidget( m_listView );
+}
+SvnBlameWidget::~SvnBlameWidget()
+{}
+
+void SvnBlameWidget::copyBlameData( QValueList<SvnBlameHolder> *blamelist )
+{
+ m_blamelist = *blamelist;
+}
+
+void SvnBlameWidget::show()
+{
+ outView()->clear();
+ outView()->setSortColumn(0);
+
+ QFont f = outView()->font();
+ f.setFixedPitch( true );
+ outView()->setFont( f );
+
+ QValueList<SvnBlameHolder>::Iterator it;
+
+ for( it = m_blamelist.begin(); it != m_blamelist.end(); ++it ){
+
+ SvnBlameHolder holder = *it;
+ SvnIntSortListItem *item = new SvnIntSortListItem(outView());
+
+ QString prettyDate = holder.date.left(16).replace(10, 1, ' ');
+
+ item->setText(0, QString::number( holder.line+1 ) );
+ item->setText(1, QString::number(holder.rev) );
+ item->setText(2, prettyDate );
+ item->setText(3, holder.author );
+ item->setText(4, holder.content );
+
+ }
+ outView()->sort();
+ QWidget::show();
+}
+
+QListView* SvnBlameWidget::outView()
+{
+ return m_listView;
+}
+
+/////////////////////////////////////////////////////////////
+
+SvnBlameFileSelectDlg::SvnBlameFileSelectDlg( QWidget *parent )
+ : QDialog( parent )
+{
+ m_selected = "";
+ setCaption( i18n("Select one file to view annotation") );
+
+ m_layout = new QGridLayout( this, 2, 2 );
+ m_view = new QListView( this );
+ m_view->addColumn( i18n("files") );
+ m_okBtn = new QPushButton( i18n("OK"), this );
+ m_cancelBtn = new QPushButton( i18n("Cancel"), this );
+ m_layout->addMultiCellWidget( m_view, 0, 0, 0, 1 );
+ m_layout->addWidget( m_okBtn, 1, 0 );
+ m_layout->addWidget( m_cancelBtn, 1, 1 );
+
+ connect( m_okBtn, SIGNAL(clicked()), this, SLOT(accept()) );
+ connect( m_cancelBtn, SIGNAL(clicked()), this, SLOT(reject()) );
+}
+SvnBlameFileSelectDlg::~SvnBlameFileSelectDlg()
+{}
+
+void SvnBlameFileSelectDlg::setCandidate( QStringList *list )
+{
+ for( QValueList<QString>::iterator it = list->begin(); it != list->end(); ++it ){
+ QListViewItem *item = new QListViewItem( m_view, *it );
+ }
+}
+
+QString SvnBlameFileSelectDlg::selected()
+{
+ return m_selected;
+}
+
+void SvnBlameFileSelectDlg::accept()
+{
+ while( true ){
+ QListViewItem *item = m_view->currentItem();
+ if( item ){
+ m_selected = item->text(0);
+ break;
+ }
+ else{
+ KMessageBox::error( this, i18n("Select file from list to view annotation") );
+ }
+ }
+ QDialog::accept();
+}
+
+#include "svn_blamewidget.moc"
diff --git a/vcs/subversion/svn_blamewidget.h b/vcs/subversion/svn_blamewidget.h
new file mode 100644
index 00000000..26bd0fa2
--- /dev/null
+++ b/vcs/subversion/svn_blamewidget.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library General Public License for more details.
+ */
+
+
+#ifndef SVN_BLAMEWIDGET_H
+#define SVN_BLAMEWIDGET_H
+
+#include <qwidget.h>
+#include <qdialog.h>
+#include <qvaluelist.h>
+class QVBoxLayout;
+class QListView;
+class QGridLayout;
+class QPushButton;
+class QStringList;
+
+class SvnBlameHolder {
+public:
+// SvnBlameHolder(){};
+// ~SvnBlameHolder(){};
+ unsigned int line;
+ long int rev;
+ QString date;
+ QString author;
+ QString content;
+};
+
+class QListView;
+
+class SvnBlameWidget : public QWidget {
+ Q_OBJECT
+public:
+ SvnBlameWidget( QWidget * parent = 0, const char * name = 0, bool modal = FALSE, WFlags f = 0 );
+ virtual ~SvnBlameWidget();
+ void copyBlameData( QValueList<SvnBlameHolder> *blamelist );
+ void show();
+ QListView* outView();
+protected:
+ QValueList <SvnBlameHolder> m_blamelist;
+
+ QVBoxLayout *m_layout;
+ QListView *m_listView;
+};
+
+class SvnBlameFileSelectDlg : public QDialog {
+ Q_OBJECT
+public:
+ SvnBlameFileSelectDlg( QWidget *parent = 0L );
+ virtual ~SvnBlameFileSelectDlg();
+ void setCandidate( QStringList *modifies );
+ QString selected();
+
+protected:
+ virtual void accept();
+
+private:
+ QGridLayout *m_layout;
+ QListView *m_view;
+ QPushButton *m_okBtn;
+ QPushButton *m_cancelBtn;
+
+ QStringList *m_candidates;
+ QString m_selected;
+};
+
+#endif
diff --git a/vcs/subversion/svn_co.ui b/vcs/subversion/svn_co.ui
new file mode 100644
index 00000000..4ea22290
--- /dev/null
+++ b/vcs/subversion/svn_co.ui
@@ -0,0 +1,335 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>svn_co</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>svn_co</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>509</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Subversion Module Checkout</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>server</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Server Settings</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Checkout &amp;from:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>serverURL</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>serverURL</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Revision:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>revision</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>revision</cstring>
+ </property>
+ <property name="text">
+ <string>HEAD</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>WinPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="title">
+ <string>This Project has Standard &amp;Trunk/Branches/Tags/Directories</string>
+ </property>
+ <property name="exclusive">
+ <bool>true</bool>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>isStandard</cstring>
+ </property>
+ <property name="text">
+ <string>Yes</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>radioButton1_2</cstring>
+ </property>
+ <property name="text">
+ <string>No</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>local</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Local Directory</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;heckout in:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>localDir</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>localDir</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Name of the newly created directory:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>newDir</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>newDir</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>191</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>ok</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>cancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>ok</sender>
+ <signal>clicked()</signal>
+ <receiver>svn_co</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>cancel</sender>
+ <signal>clicked()</signal>
+ <receiver>svn_co</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/vcs/subversion/svn_commitdlgbase.ui b/vcs/subversion/svn_commitdlgbase.ui
new file mode 100644
index 00000000..9151d566
--- /dev/null
+++ b/vcs/subversion/svn_commitdlgbase.ui
@@ -0,0 +1,131 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SvnCommitDlgBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>SvnCommitDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>514</width>
+ <height>305</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string></string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView" row="0" column="0" rowspan="1" colspan="3">
+ <column>
+ <property name="text">
+ <string>Column 1</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string>New Item</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>listView1</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>335</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>keepLocksChk</cstring>
+ </property>
+ <property name="text">
+ <string>Keep Locks</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="2">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pushButton3</cstring>
+ </property>
+ <property name="text">
+ <string>O&amp;K</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pushButton3_2</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;ancel</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QCheckBox" row="1" column="1">
+ <property name="name">
+ <cstring>recursiveChk</cstring>
+ </property>
+ <property name="text">
+ <string>Recursive</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>pushButton3</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnCommitDlgBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>pushButton3_2</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnCommitDlgBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/vcs/subversion/svn_copydlgwidget.ui b/vcs/subversion/svn_copydlgwidget.ui
new file mode 100644
index 00000000..00a4d5c7
--- /dev/null
+++ b/vcs/subversion/svn_copydlgwidget.ui
@@ -0,0 +1,238 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SvnCopyDialogBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>SvnCopyDialogBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>439</width>
+ <height>433</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Subversion Copy</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>reqEdit</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="5" column="1">
+ <property name="name">
+ <cstring>okBtn</cstring>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ <spacer row="5" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>110</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="5" column="2">
+ <property name="name">
+ <cstring>cancelBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="4" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>buttonGroup3</cstring>
+ </property>
+ <property name="title">
+ <string>Destination</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KURLRequester" row="1" column="0">
+ <property name="name">
+ <cstring>destRequester</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Specify either the full repository URL or local working path</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Requested Local Path</string>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="3" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>buttonGroup2</cstring>
+ </property>
+ <property name="title">
+ <string>Source Revision</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KIntNumInput" row="0" column="1">
+ <property name="name">
+ <cstring>revnumInput</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minValue">
+ <number>-1</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>revnumRadio</cstring>
+ </property>
+ <property name="text">
+ <string>Specify by number:</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>revkindRadio</cstring>
+ </property>
+ <property name="text">
+ <string>Specify by keyword:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string>HEAD</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BASE</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>WORKING</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>revkindCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Source</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KLineEdit" row="2" column="0">
+ <property name="name">
+ <cstring>srcEdit</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>urlRadio</cstring>
+ </property>
+ <property name="text">
+ <string>Specify by the repository URL of this item</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>pathRadio</cstring>
+ </property>
+ <property name="text">
+ <string>Specify by local path of this item</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>okBtn</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnCopyDialogBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>cancelBtn</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnCopyDialogBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/vcs/subversion/svn_copywidget.cpp b/vcs/subversion/svn_copywidget.cpp
new file mode 100644
index 00000000..a5d74bcb
--- /dev/null
+++ b/vcs/subversion/svn_copywidget.cpp
@@ -0,0 +1,75 @@
+#include "svn_copywidget.h"
+#include <klineedit.h>
+#include <kurl.h>
+#include "subversion_global.h"
+#include <kurlrequester.h>
+#include <knuminput.h>
+#include <kcombobox.h>
+#include <qradiobutton.h>
+
+SvnCopyDialog::SvnCopyDialog( const QString &reqPath, SvnGlobal::SvnInfoHolder *holder, QWidget *parent )
+ : SvnCopyDialogBase( parent )
+ , m_holder(holder)
+{
+ reqEdit->setText( reqPath );
+
+ connect( urlRadio, SIGNAL(clicked()), this, SLOT(setSourceAsUrl()) );
+ connect( pathRadio, SIGNAL(clicked()), this, SLOT(setSourceAsLocalPath()) );
+ connect( revnumRadio, SIGNAL(toggled(bool)), revnumInput, SLOT(setEnabled(bool)) );
+ connect( revnumRadio, SIGNAL(toggled(bool)), revkindCombo, SLOT(setDisabled(bool)) );
+
+ // In many cases, users copy from reository to repository. This is for making tag/branche.
+ // The case where copying from local path to repository may be lesser than the above one.
+ // Thus, by default retrieve the repository URL of the given local path
+ urlRadio->setChecked( true );
+ srcEdit->setText( m_holder->url.prettyURL() );
+ // Also, revision is set to HEAD by default
+ revkindRadio->setChecked( true );
+ revkindCombo->insertItem( "HEAD" );
+}
+
+SvnCopyDialog::~SvnCopyDialog()
+{
+}
+
+KURL SvnCopyDialog::sourceUrl()
+{
+ return KURL( srcEdit->text() );
+}
+
+int SvnCopyDialog::revision()
+{
+ if( revnumRadio->isChecked() )
+ return revnumInput->value();
+ else
+ return -1;
+}
+
+QString SvnCopyDialog::revKind()
+{
+ if( revkindRadio->isChecked() )
+ return revkindCombo->currentText();
+ else
+ return QString("");
+}
+
+KURL SvnCopyDialog::destUrl()
+{
+ return KURL( destRequester->url() );
+}
+
+void SvnCopyDialog::setSourceAsUrl()
+{
+ srcEdit->setText( m_holder->url.prettyURL() );
+ revkindCombo->clear();
+ revkindCombo->insertItem( "HEAD" );
+}
+
+void SvnCopyDialog::setSourceAsLocalPath()
+{
+ srcEdit->setText( reqEdit->text() );
+ revkindCombo->clear();
+ revkindCombo->insertItem( "WORKING" );
+}
+
+#include "svn_copywidget.moc"
diff --git a/vcs/subversion/svn_copywidget.h b/vcs/subversion/svn_copywidget.h
new file mode 100644
index 00000000..cc00636d
--- /dev/null
+++ b/vcs/subversion/svn_copywidget.h
@@ -0,0 +1,32 @@
+#ifndef SVN_COPYWIDGET_H
+#define SVN_COPYWIDGET_H
+
+#include "svn_copydlgwidget.h"
+
+namespace SvnGlobal
+{
+ class SvnInfoHolder;
+}
+class KURL;
+
+class SvnCopyDialog : public SvnCopyDialogBase
+{
+ Q_OBJECT
+public:
+ SvnCopyDialog( const QString &reqPath, SvnGlobal::SvnInfoHolder *holder, QWidget *parent );
+ ~SvnCopyDialog();
+
+ KURL sourceUrl();
+ int revision();
+ QString revKind();
+ KURL destUrl();
+
+public slots:
+ void setSourceAsUrl();
+ void setSourceAsLocalPath();
+
+private:
+ SvnGlobal::SvnInfoHolder *m_holder;
+};
+
+#endif
diff --git a/vcs/subversion/svn_fileselectdlg_commit.cpp b/vcs/subversion/svn_fileselectdlg_commit.cpp
new file mode 100644
index 00000000..4f4cdceb
--- /dev/null
+++ b/vcs/subversion/svn_fileselectdlg_commit.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library 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.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#include "svn_fileselectdlg_commit.h"
+#include "subversion_fileinfo.h"
+#include "subversion_part.h"
+#include <kurl.h>
+#include <qstring.h>
+#include <qlistview.h>
+#include <qfileinfo.h>
+#include <qcheckbox.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include "kdevmainwindow.h"
+#include <klocale.h>
+
+#include <kdevproject.h>
+
+SVNFileSelectDlgCommit::SVNFileSelectDlgCommit( KURL::List &urls, subversionPart *part, QWidget* parent)
+ :SvnCommitDlgBase( parent, "svnfileselectcommitdlg", true )
+ ,m_part(part)
+{
+ this->setCaption(i18n("Select Files to Commit"));
+ listView()->clear();
+ listView()->setColumnText(0, i18n("select") ); //col 0
+ listView()->addColumn( i18n("status") ); //col 1
+ listView()->addColumn( i18n("URL to commit") ); //col 2
+ listView()->setColumnWidthMode( 2, QListView::Maximum );
+ listView()->setSorting( 2, true );
+ recursiveChk->setChecked(false);
+ keepLocksChk->setChecked(false);
+
+
+ const VCSFileInfoMap *vcsMap;
+ VCSFileInfo vcsInfo;
+ KURL::List tobeCommittedUrls;
+
+ for( QValueListConstIterator<KURL> it = urls.begin(); it != urls.end(); ++it ){
+ KURL oneUrl(*it);
+ QFileInfo fileInfo(oneUrl.path());
+ //fileInfo.convertToAbs();
+
+ if (fileInfo.isFile()){
+ KURL base_url( part->project()->projectDirectory()+"/" );
+ QString dirPath = KURL::relativeURL( base_url, fileInfo.dirPath(TRUE) );
+ vcsMap = ((SVNFileInfoProvider*)part->fileInfoProvider()) ->
+ statusExt(dirPath, false/*repository access*/, true/*recurse*/, false/*getall*/, true/*noIgnore*/);
+ vcsInfo = (*vcsMap)[fileInfo.fileName()];
+ if( vcsInfo.state == VCSFileInfo::Added || vcsInfo.state == VCSFileInfo::Modified ||
+ vcsInfo.state == VCSFileInfo::Deleted || vcsInfo.state == VCSFileInfo::Replaced ){
+
+ this->insertItem( VCSFileInfo::state2String( vcsInfo.state ), oneUrl );
+// tobeCommittedUrls.push_back(oneUrl);
+// kdDebug(9036) << "slotCommit() : added AS FILE: " << oneUrl.prettyURL() << endl;
+
+ }
+ else{
+ kdDebug(9036) << "slotCommit() @ FileCase ignoring " << oneUrl.prettyURL() << endl;
+ }
+ }
+ else if (fileInfo.isDir()){
+ KURL base_url( part->project()->projectDirectory()+"/" );
+ QString dirPath = KURL::relativeURL( base_url, fileInfo.absFilePath() );
+ vcsMap = ((SVNFileInfoProvider*)part->fileInfoProvider()) ->
+ statusExt(dirPath, false/*repository access*/, true/*recurse*/, false/*getall*/, true/*noIgnore*/);
+ for (VCSFileInfoMap::ConstIterator it=vcsMap->begin(); it!=vcsMap->end(); ++it){
+
+ vcsInfo = it.data();
+// QString absPathStr( fileInfo.absFilePath() + "/" + it.key() );
+ QString absPathStr( fileInfo.filePath() + "/" + it.key() );
+ KURL urlFromStatus( absPathStr );
+ if( vcsInfo.state == VCSFileInfo::Added || vcsInfo.state == VCSFileInfo::Modified ||
+ vcsInfo.state == VCSFileInfo::Deleted || vcsInfo.state == VCSFileInfo::Replaced){
+
+ this->insertItem( VCSFileInfo::state2String( vcsInfo.state ), urlFromStatus );
+
+// tobeCommittedUrls.push_back( urlFromStatus );
+// kdDebug(9036) << "slotCommit() @ DirCase adding " << urlFromStatus.prettyURL() << endl;
+ }
+ else{
+ kdDebug(9036) << "slotCommit() @ DirCase ignoring " << urlFromStatus.prettyURL() << endl;
+ }
+
+ }
+ }
+ else if ( !fileInfo.exists() ){
+ // maybe deleted files
+ this->insertItem( VCSFileInfo::state2String( VCSFileInfo::Deleted ), oneUrl );
+ }
+ }
+
+}
+SVNFileSelectDlgCommit::~SVNFileSelectDlgCommit()
+{
+}
+
+int SVNFileSelectDlgCommit::exec()
+{
+ if (listView()->childCount() <= 0){
+ //TODO if klauncher fails, this spot is also reached. We should show correct error message to user
+ KMessageBox::information( (QWidget*)m_part->project()->mainWindow()->main(), i18n("No added/modified/deleted file(s) to commit") );
+ return QDialog::Rejected;
+ }
+ else{
+ return SvnCommitDlgBase::exec();
+ }
+}
+void SVNFileSelectDlgCommit::insertItem( QString status, KURL url )
+{
+ QCheckListItem *item = new QCheckListItem( listView(), "", QCheckListItem::CheckBox );
+ item->setText( 1, status );
+ item->setText( 2, url.path() );
+ item->setOn(true);
+}
+KURL::List SVNFileSelectDlgCommit::checkedUrls()
+{
+ QPtrList<QListViewItem> lst;
+ QListViewItemIterator it( listView() );
+ KURL::List tobeCommittedUrls;
+
+ for ( ; it.current() ; ++it ) {
+ if ( ((QCheckListItem*)(it.current()))->isOn() ){
+ KURL tmpurl( it.current()->text(2) );
+ tobeCommittedUrls.push_back( tmpurl );
+ }
+ }
+ return tobeCommittedUrls;
+
+}
+QListView* SVNFileSelectDlgCommit::listView()
+{
+ return listView1;
+}
+
+bool SVNFileSelectDlgCommit::recursive()
+{
+ return recursiveChk->isChecked();
+}
+bool SVNFileSelectDlgCommit::keepLocks()
+{
+ return keepLocksChk->isChecked();
+}
+
+#include "svn_fileselectdlg_commit.moc"
+
diff --git a/vcs/subversion/svn_fileselectdlg_commit.h b/vcs/subversion/svn_fileselectdlg_commit.h
new file mode 100644
index 00000000..acd95ebb
--- /dev/null
+++ b/vcs/subversion/svn_fileselectdlg_commit.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library 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.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _svnfileselectdlgcommit_
+#define _svnfileselectdlgcommit_
+
+#include "svn_commitdlgbase.h"
+#include <qdialog.h>
+#include <kurl.h>
+
+class QString;
+class KURL;
+class QListView;
+class subversionPart;
+
+class SVNFileSelectDlgCommit : public SvnCommitDlgBase{
+
+Q_OBJECT
+
+public:
+ SVNFileSelectDlgCommit( KURL::List&, subversionPart* part, QWidget* parent = 0 );
+ ~SVNFileSelectDlgCommit();
+ void insertItem( QString status, KURL url );
+ KURL::List checkedUrls();
+ bool recursive();
+ bool keepLocks();
+
+public slots:
+ int exec();
+protected:
+ QListView* listView();
+ subversionPart *m_part;
+};
+
+#endif
diff --git a/vcs/subversion/svn_kio.cpp b/vcs/subversion/svn_kio.cpp
new file mode 100644
index 00000000..c5c8dfe6
--- /dev/null
+++ b/vcs/subversion/svn_kio.cpp
@@ -0,0 +1,2155 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Mickael Marchand <marchand@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <qcstring.h>
+#include <qsocket.h>
+#include <qdatetime.h>
+#include <qbitarray.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 <kmessagebox.h>
+#include <kinstance.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <ksock.h>
+#include <dcopclient.h>
+#include <qcstring.h>
+
+#include <subversion-1/svn_sorts.h>
+#include <subversion-1/svn_path.h>
+#include <subversion-1/svn_utf.h>
+#include <subversion-1/svn_ra.h>
+#include <subversion-1/svn_time.h>
+#include <subversion-1/svn_cmdline.h>
+
+#include <kmimetype.h>
+#include <qfile.h>
+
+#include "svn_kio.h"
+#include <apr_portable.h>
+// #include "commitdlg.h"
+#include <ktextedit.h>
+
+using namespace KIO;
+using namespace SvnGlobal;
+
+typedef struct
+{
+ /* Holds the directory that corresponds to the REPOS_URL at RA->open()
+ * time. When callbacks specify a relative path, they are joined with
+ * this base directory. */
+ const char *base_dir;
+ svn_wc_adm_access_t *base_access;
+
+ /* An array of svn_client_commit_item_t * structures, present only
+ * during working copy commits. */
+ apr_array_header_t *commit_items;
+
+ /* A hash of svn_config_t's, keyed off file name (i.e. the contents of
+ * ~/.subversion/config end up keyed off of 'config'). */
+ apr_hash_t *config;
+
+ /* The pool to use for session-related items. */
+ apr_pool_t *pool;
+
+} svn_client__callback_baton_t;
+
+static svn_error_t *
+open_tmp_file (apr_file_t **fp,
+ void *callback_baton,
+ apr_pool_t *pool)
+{
+ svn_client__callback_baton_t *cb = (svn_client__callback_baton_t *) callback_baton;
+ const char *truepath;
+ const char *ignored_filename;
+
+ if (cb->base_dir)
+ truepath = apr_pstrdup (pool, cb->base_dir);
+ else
+ truepath = "";
+
+ /* Tack on a made-up filename. */
+ truepath = svn_path_join (truepath, "tempfile", pool);
+
+ /* Open a unique file; use APR_DELONCLOSE. */
+ SVN_ERR (svn_io_open_unique_file (fp, &ignored_filename,
+ truepath, ".tmp", TRUE, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *write_to_string(void *baton, const char *data, apr_size_t *len) {
+ kbaton *tb = ( kbaton* )baton;
+ svn_stringbuf_appendbytes(tb->target_string, data, *len);
+ return SVN_NO_ERROR;
+}
+
+static int
+compare_items_as_paths (const svn_sort__item_t*a, const svn_sort__item_t*b) {
+ return svn_path_compare_paths ((const char *)a->key, (const char *)b->key);
+}
+
+kio_svnProtocol::kio_svnProtocol(const QCString &pool_socket, const QCString &app_socket)
+ : SlaveBase("kio_svn", pool_socket, app_socket) {
+ kdDebug(9036) << "kio_svnProtocol::kio_svnProtocol()" << endl;
+
+ m_counter = 0;
+
+ apr_initialize();
+ // Make sure to properly initialize svn client, besides other things, this sets up
+ // NLS support for environments that don't use UTF-8
+ svn_cmdline_init("kdevsvnd",NULL);
+ // CleanUP ctx preventing crash in svn_client_update and other
+ memset(&ctx, 0, sizeof(ctx));
+ pool = svn_pool_create (NULL);
+
+ svn_error_t *err = svn_client_create_context(&ctx, pool);
+ if ( err ) {
+ kdDebug(9036) << "kio_svnProtocol::kio_svnProtocol() create_context ERROR" << endl;
+ error( KIO::ERR_SLAVE_DEFINED, err->message );
+ return;
+ }
+
+ err = svn_config_ensure (NULL,pool);
+ if ( err ) {
+ kdDebug(9036) << "kio_svnProtocol::kio_svnProtocol() configensure ERROR" << endl;
+ error( KIO::ERR_SLAVE_DEFINED, err->message );
+ return;
+ }
+ svn_config_get_config (&ctx->config, NULL, pool);
+
+ ctx->log_msg_func = kio_svnProtocol::commitLogPrompt;
+ ctx->log_msg_baton = this; //pass this so that we can get a dcopClient from it
+ //TODO
+ ctx->cancel_func = NULL;
+ // progress notifications
+ ctx->progress_func = kio_svnProtocol::progressCallback;
+ ctx->progress_baton = this;
+
+ apr_array_header_t *providers = apr_array_make(pool, 15, sizeof(svn_auth_provider_object_t *));
+
+ svn_auth_provider_object_t *provider;
+
+ //disk cache
+ svn_client_get_simple_provider(&provider,pool);
+ APR_ARRAY_PUSH(providers, svn_auth_provider_object_t*) = provider;
+ svn_client_get_username_provider(&provider,pool);
+ APR_ARRAY_PUSH(providers, svn_auth_provider_object_t*) = provider;
+
+ //interactive prompt
+ svn_client_get_simple_prompt_provider (&provider,kio_svnProtocol::checkAuth,this,2,pool);
+ APR_ARRAY_PUSH(providers, svn_auth_provider_object_t*) = provider;
+ //we always ask user+pass, no need for a user only question
+/* svn_client_get_username_prompt_provider
+ * (&provider,kio_svnProtocol::checkAuth,this,2,pool);
+ APR_ARRAY_PUSH(providers, svn_auth_provider_object_t*) = provider;*/
+
+ //SSL disk cache, keep that one, because it does nothing bad :)
+ svn_client_get_ssl_server_trust_file_provider (&provider, pool);
+ APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
+ svn_client_get_ssl_client_cert_file_provider (&provider, pool);
+ APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
+ svn_client_get_ssl_client_cert_pw_file_provider (&provider, pool);
+ APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
+
+ //SSL interactive prompt, where things get hard
+ svn_client_get_ssl_server_trust_prompt_provider (&provider, kio_svnProtocol::trustSSLPrompt, (void*)this, pool);
+ APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
+ svn_client_get_ssl_client_cert_prompt_provider (&provider, kio_svnProtocol::clientCertSSLPrompt, (void*)this, 2, pool);
+ APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
+ svn_client_get_ssl_client_cert_pw_prompt_provider (&provider, kio_svnProtocol::clientCertPasswdPrompt, (void*)this, 2, pool);
+ APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
+
+ svn_auth_open(&ctx->auth_baton, providers, pool);
+}
+
+kio_svnProtocol::~kio_svnProtocol(){
+ kdDebug(9036) << "kio_svnProtocol::~kio_svnProtocol()" << endl;
+ svn_pool_destroy(pool);
+ apr_terminate();
+}
+
+void kio_svnProtocol::initNotifier(bool is_checkout, bool is_export, bool suppress_final_line, apr_pool_t *spool) {
+ m_counter=0;//reset counter
+ ctx->notify_func = kio_svnProtocol::notify;
+ struct notify_baton *nb = ( struct notify_baton* )apr_palloc(spool, sizeof( struct notify_baton ) );
+ nb->master = this;
+ nb->received_some_change = FALSE;
+ nb->sent_first_txdelta = FALSE;
+ nb->is_checkout = is_checkout;
+ nb->is_export = is_export;
+ nb->suppress_final_line = suppress_final_line;
+ nb->in_external = FALSE;
+ nb->had_print_error = FALSE;
+ nb->pool = svn_pool_create (spool);
+
+ ctx->notify_baton = nb;
+}
+
+svn_error_t* kio_svnProtocol::checkAuth(svn_auth_cred_simple_t **cred, void *baton, const char *realm, const char *username, svn_boolean_t may_save, apr_pool_t *pool) {
+ kdDebug(9036) << "kio_svnProtocol::checkAuth() " << endl;
+ kio_svnProtocol *p = ( kio_svnProtocol* )baton;
+ svn_auth_cred_simple_t *ret = (svn_auth_cred_simple_t*)apr_pcalloc (pool, sizeof (*ret));
+
+ p->info.keepPassword = true;
+ p->info.verifyPath=true;
+ kdDebug(9036 ) << "auth current URL : " << p->myURL.url() << endl;
+ p->info.url = p->myURL;
+ p->info.username = username; //( const char* )svn_auth_get_parameter( p->ctx->auth_baton, SVN_AUTH_PARAM_DEFAULT_USERNAME );
+ if (realm) {
+ p->info.prompt = i18n("Username and Password for %1.").arg(realm);
+ }
+
+// if ( !p->checkCachedAuthentication( p->info ) ){
+ p->openPassDlg( p->info );
+// }
+ ret->username = apr_pstrdup(pool, p->info.username.utf8());
+ ret->password = apr_pstrdup(pool, p->info.password.utf8());
+ if (may_save) ret->may_save = p->info.keepPassword;
+ *cred = ret;
+ return SVN_NO_ERROR;
+}
+
+void kio_svnProtocol::recordCurrentURL(const KURL& url) {
+ myURL = url;
+}
+
+//don't implement mimeType() until we don't need to download the whole file
+
+void kio_svnProtocol::get(const KURL& url ){
+ kdDebug(9036) << "kio_svn::get(const KURL& url)" << endl ;
+
+ QString remoteServer = url.host();
+ infoMessage(i18n("Looking for %1...").arg( remoteServer ) );
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ kbaton *bt = (kbaton*)apr_pcalloc(subpool, sizeof(*bt));
+ bt->target_string = svn_stringbuf_create("", subpool);
+ bt->string_stream = svn_stream_create(bt,subpool);
+ svn_stream_set_write(bt->string_stream,write_to_string);
+
+ QString target = makeSvnURL( url );
+ kdDebug(9036) << "SvnURL: " << target << endl;
+ recordCurrentURL( KURL( target ) );
+
+ //find the requested revision
+ svn_opt_revision_t rev;
+ svn_opt_revision_t endrev;
+ int idx = target.findRev( "?rev=" );
+ if ( idx != -1 ) {
+ QString revstr = target.mid( idx+5 );
+#if 0
+ kdDebug(9036) << "revision string found " << revstr << endl;
+ if ( revstr == "HEAD" ) {
+ rev.kind = svn_opt_revision_head;
+ kdDebug(9036) << "revision searched : HEAD" << endl;
+ } else {
+ rev.kind = svn_opt_revision_number;
+ rev.value.number = revstr.toLong();
+ kdDebug(9036) << "revision searched : " << rev.value.number << endl;
+ }
+#endif
+ svn_opt_parse_revision( &rev, &endrev, revstr.utf8(), subpool );
+ target = target.left( idx );
+ kdDebug(9036) << "new target : " << target << endl;
+ } else {
+ kdDebug(9036) << "no revision given. searching HEAD " << endl;
+ rev.kind = svn_opt_revision_head;
+ }
+ initNotifier(false, false, false, subpool);
+
+ svn_error_t *err = svn_client_cat (bt->string_stream, svn_path_canonicalize( target.utf8(),subpool ),&rev,ctx, subpool);
+ if ( err ) {
+ error( KIO::ERR_SLAVE_DEFINED, err->message );
+ svn_pool_destroy( subpool );
+ return;
+ }
+
+ // Send the mimeType as soon as it is known
+ QByteArray *cp = new QByteArray();
+ cp->setRawData( bt->target_string->data, bt->target_string->len );
+ KMimeType::Ptr mt = KMimeType::findByContent(*cp);
+ kdDebug(9036) << "KMimeType returned : " << mt->name() << endl;
+ mimeType( mt->name() );
+
+ totalSize(bt->target_string->len);
+
+ //send data
+ data(*cp);
+
+ data(QByteArray()); // empty array means we're done sending the data
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::stat(const KURL & url){
+ kdDebug(9036) << "kio_svn::stat(const KURL& url) : " << url.url() << endl ;
+
+ void *ra_baton, *session;
+ svn_ra_plugin_t *ra_lib;
+ svn_node_kind_t kind;
+ apr_pool_t *subpool = svn_pool_create (pool);
+
+ QString target = makeSvnURL( url);
+ kdDebug(9036) << "SvnURL: " << target << endl;
+ recordCurrentURL( KURL( target ) );
+
+ //find the requested revision
+ svn_opt_revision_t rev;
+ svn_opt_revision_t endrev;
+ int idx = target.findRev( "?rev=" );
+ if ( idx != -1 ) {
+ QString revstr = target.mid( idx+5 );
+#if 0
+ kdDebug(9036) << "revision string found " << revstr << endl;
+ if ( revstr == "HEAD" ) {
+ rev.kind = svn_opt_revision_head;
+ kdDebug(9036) << "revision searched : HEAD" << endl;
+ } else {
+ rev.kind = svn_opt_revision_number;
+ rev.value.number = revstr.toLong();
+ kdDebug(9036) << "revision searched : " << rev.value.number << endl;
+ }
+#endif
+ svn_opt_parse_revision( &rev, &endrev, revstr.utf8( ), subpool );
+ target = target.left( idx );
+ kdDebug(9036) << "new target : " << target << endl;
+ } else {
+ kdDebug(9036) << "no revision given. searching HEAD " << endl;
+ rev.kind = svn_opt_revision_head;
+ }
+
+ //init
+ svn_error_t *err = svn_ra_init_ra_libs(&ra_baton,subpool);
+ if ( err ) {
+ kdDebug(9036) << "init RA libs failed : " << err->message << endl;
+ return;
+ }
+ //find RA libs
+ err = svn_ra_get_ra_library(&ra_lib,ra_baton,svn_path_canonicalize( target.utf8(), subpool ),subpool);
+ if ( err ) {
+ kdDebug(9036) << "RA get libs failed : " << err->message << endl;
+ return;
+ }
+ kdDebug(9036) << "RA init completed" << endl;
+
+ //start session
+ svn_ra_callbacks_t *cbtable = (svn_ra_callbacks_t*)apr_pcalloc(subpool, sizeof(*cbtable));
+ kio_svn_callback_baton_t *callbackbt = (kio_svn_callback_baton_t*)apr_pcalloc(subpool, sizeof( *callbackbt ));
+
+ cbtable->open_tmp_file = open_tmp_file;
+ cbtable->get_wc_prop = NULL;
+ cbtable->set_wc_prop = NULL;
+ cbtable->push_wc_prop = NULL;
+ cbtable->auth_baton = ctx->auth_baton;
+
+ callbackbt->base_dir = target.utf8();
+ callbackbt->pool = subpool;
+ callbackbt->config = ctx->config;
+
+ err = ra_lib->open(&session,svn_path_canonicalize( target.utf8(), subpool ),cbtable,callbackbt,ctx->config,subpool);
+ if ( err ) {
+ kdDebug(9036)<< "Open session " << err->message << endl;
+ return;
+ }
+ kdDebug(9036) << "Session opened to " << target << endl;
+ //find number for HEAD
+ if (rev.kind == svn_opt_revision_head) {
+ err = ra_lib->get_latest_revnum(session,&rev.value.number,subpool);
+ if ( err ) {
+ kdDebug(9036)<< "Latest RevNum " << err->message << endl;
+ return;
+ }
+ kdDebug(9036) << "Got rev " << rev.value.number << endl;
+ }
+
+ //get it
+ ra_lib->check_path(session,"",rev.value.number,&kind,subpool);
+ kdDebug(9036) << "Checked Path" << endl;
+ UDSEntry entry;
+ switch ( kind ) {
+ case svn_node_file:
+ kdDebug(9036) << "::stat result : file" << endl;
+ createUDSEntry(url.filename(),"",0,false,0,entry);
+ statEntry( entry );
+ break;
+ case svn_node_dir:
+ kdDebug(9036) << "::stat result : directory" << endl;
+ createUDSEntry(url.filename(),"",0,true,0,entry);
+ statEntry( entry );
+ break;
+ case svn_node_unknown:
+ case svn_node_none:
+ //error XXX
+ default:
+ kdDebug(9036) << "::stat result : UNKNOWN ==> WOW :)" << endl;
+ ;
+ }
+ finished();
+ svn_pool_destroy( subpool );
+}
+
+void kio_svnProtocol::listDir(const KURL& url){
+ kdDebug(9036) << "kio_svn::listDir(const KURL& url) : " << url.url() << endl ;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ apr_hash_t *dirents;
+
+ QString target = makeSvnURL( url);
+ kdDebug(9036) << "SvnURL: " << target << endl;
+ recordCurrentURL( KURL( target ) );
+
+ //find the requested revision
+ svn_opt_revision_t rev;
+ svn_opt_revision_t endrev;
+ int idx = target.findRev( "?rev=" );
+ if ( idx != -1 ) {
+ QString revstr = target.mid( idx+5 );
+ svn_opt_parse_revision( &rev, &endrev, revstr.utf8(), subpool );
+#if 0
+ kdDebug(9036) << "revision string found " << revstr << endl;
+ if ( revstr == "HEAD" ) {
+ rev.kind = svn_opt_revision_head;
+ kdDebug(9036) << "revision searched : HEAD" << endl;
+ } else {
+ rev.kind = svn_opt_revision_number;
+ rev.value.number = revstr.toLong();
+ kdDebug(9036) << "revision searched : " << rev.value.number << endl;
+ }
+#endif
+ target = target.left( idx );
+ kdDebug(9036) << "new target : " << target << endl;
+ } else {
+ kdDebug(9036) << "no revision given. searching HEAD " << endl;
+ rev.kind = svn_opt_revision_head;
+ }
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_ls (&dirents, svn_path_canonicalize( target.utf8(), subpool ), &rev, false, ctx, subpool);
+ if ( err ) {
+ error( KIO::ERR_SLAVE_DEFINED, err->message );
+ svn_pool_destroy( subpool );
+ return;
+ }
+
+ apr_array_header_t *array;
+ int i;
+
+ array = svn_sort__hash (dirents, compare_items_as_paths, subpool);
+
+ UDSEntry entry;
+ for (i = 0; i < array->nelts; ++i) {
+ entry.clear();
+ const char *utf8_entryname, *native_entryname;
+ svn_dirent_t *dirent;
+ svn_sort__item_t *item;
+
+ item = &APR_ARRAY_IDX (array, i, svn_sort__item_t);
+
+ utf8_entryname = (const char*)item->key;
+
+ dirent = (svn_dirent_t*)apr_hash_get (dirents, utf8_entryname, item->klen);
+
+ svn_utf_cstring_from_utf8 (&native_entryname, utf8_entryname, subpool);
+ const char *native_author = NULL;
+
+ //XXX BUGGY
+/* apr_time_exp_t timexp;
+ apr_time_exp_lt(&timexp, dirent->time);
+ apr_os_exp_time_t *ostime;
+ apr_os_exp_time_get( &ostime, &timexp);
+
+ time_t mtime = mktime( ostime );*/
+
+ if (dirent->last_author)
+ svn_utf_cstring_from_utf8 (&native_author, dirent->last_author, subpool);
+
+ if ( createUDSEntry(QString( native_entryname ), QString( native_author ), dirent->size,
+ dirent->kind==svn_node_dir ? true : false, 0, entry) )
+ listEntry( entry, false );
+ }
+ listEntry( entry, true );
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+bool kio_svnProtocol::createUDSEntry( const QString& filename, const QString& user, long long int size, bool isdir, time_t mtime, UDSEntry& entry) {
+ kdDebug(9036) << "MTime : " << ( long )mtime << endl;
+ kdDebug(9036) << "UDS filename : " << filename << endl;
+ 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_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;
+}
+
+// not used, at least for KDevelop
+// void kio_svnProtocol::copy(const KURL & src, const KURL& dest, int /*permissions*/, bool /*overwrite*/) {
+// kdDebug(9036) << "kio_svnProtocol::copy() Source : " << src.url() << " Dest : " << dest.url() << endl;
+//
+// apr_pool_t *subpool = svn_pool_create (pool);
+// svn_client_commit_info_t *commit_info = NULL;
+//
+// KURL nsrc = src;
+// KURL ndest = dest;
+// nsrc.setProtocol( chooseProtocol( src.protocol() ) );
+// ndest.setProtocol( chooseProtocol( dest.protocol() ) );
+// QString srcsvn = nsrc.url();
+// QString destsvn = ndest.url();
+//
+// recordCurrentURL( nsrc );
+//
+// //find the requested revision
+// svn_opt_revision_t rev;
+// int idx = srcsvn.findRev( "?rev=" );
+// if ( idx != -1 ) {
+// QString revstr = srcsvn.mid( idx+5 );
+// kdDebug(9036) << "revision string found " << revstr << endl;
+// if ( revstr == "HEAD" ) {
+// rev.kind = svn_opt_revision_head;
+// kdDebug(9036) << "revision searched : HEAD" << endl;
+// } else {
+// rev.kind = svn_opt_revision_number;
+// rev.value.number = revstr.toLong();
+// kdDebug(9036) << "revision searched : " << rev.value.number << endl;
+// }
+// srcsvn = srcsvn.left( idx );
+// kdDebug(9036) << "new src : " << srcsvn << endl;
+// } else {
+// kdDebug(9036) << "no revision given. searching HEAD " << endl;
+// rev.kind = svn_opt_revision_head;
+// }
+//
+// initNotifier(false, false, false, subpool);
+// svn_error_t *err = svn_client_copy(&commit_info, srcsvn.utf8(), &rev, destsvn.utf8(), ctx, subpool);
+// if ( err ) {
+// error( KIO::ERR_SLAVE_DEFINED, err->message );
+// svn_pool_destroy (subpool);
+// }
+//
+// finished();
+// svn_pool_destroy (subpool);
+// }
+
+void kio_svnProtocol::mkdir( const KURL::List& list, int /*permissions*/ ) {
+ kdDebug(9036) << "kio_svnProtocol::mkdir(LIST) : " << list << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ svn_client_commit_info_t *commit_info = NULL;
+
+ recordCurrentURL( list[ 0 ] );
+
+ apr_array_header_t *targets = apr_array_make(subpool, list.count()+1, sizeof(const char *));
+
+ KURL::List::const_iterator it = list.begin(), end = list.end();
+ for ( ; it != end; ++it ) {
+ QString cur = makeSvnURL( *it );
+ kdDebug( 9036 ) << "kio_svnProtocol::mkdir raw url for subversion : " << cur << endl;
+ const char *_target = apr_pstrdup( subpool, svn_path_canonicalize( apr_pstrdup( subpool, cur.utf8() ), subpool ) );
+ (*(( const char ** )apr_array_push(( apr_array_header_t* )targets)) ) = _target;
+ }
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_mkdir(&commit_info,targets,ctx,subpool);
+ if ( err ) {
+ error( KIO::ERR_COULD_NOT_MKDIR, QString::fromLocal8Bit(err->message) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::mkdir( const KURL& url, int /*permissions*/ ) {
+ kdDebug(9036) << "kio_svnProtocol::mkdir() : " << url.url() << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ svn_client_commit_info_t *commit_info = NULL;
+
+ QString target = makeSvnURL( url);
+ kdDebug(9036) << "SvnURL: " << target << endl;
+ recordCurrentURL( KURL( target ) );
+
+ apr_array_header_t *targets = apr_array_make(subpool, 2, sizeof(const char *));
+ (*(( const char ** )apr_array_push(( apr_array_header_t* )targets)) ) = apr_pstrdup( subpool, target.utf8() );
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_mkdir(&commit_info,targets,ctx,subpool);
+ if ( err ) {
+ error( KIO::ERR_COULD_NOT_MKDIR, err->message );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::del( const KURL& url, bool /*isfile*/ ) {
+ kdDebug(9036) << "kio_svnProtocol::del() : " << url.url() << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ svn_client_commit_info_t *commit_info = NULL;
+
+ QString target = makeSvnURL(url);
+ kdDebug(9036) << "SvnURL: " << target << endl;
+ recordCurrentURL( KURL( target ) );
+
+ apr_array_header_t *targets = apr_array_make(subpool, 2, sizeof(const char *));
+ (*(( const char ** )apr_array_push(( apr_array_header_t* )targets)) ) = apr_pstrdup( subpool, target.utf8() );
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_delete(&commit_info,targets,false/*force remove locally modified files in wc*/,ctx,subpool);
+ if ( err ) {
+ error( KIO::ERR_CANNOT_DELETE, err->message );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::rename(const KURL& src, const KURL& dest, bool /*overwrite*/) {
+ kdDebug(9036) << "kio_svnProtocol::rename() Source : " << src.url() << " Dest : " << dest.url() << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ svn_client_commit_info_t *commit_info = NULL;
+
+ KURL nsrc = src;
+ KURL ndest = dest;
+ nsrc.setProtocol( chooseProtocol( src.protocol() ) );
+ ndest.setProtocol( chooseProtocol( dest.protocol() ) );
+ QString srcsvn = nsrc.url();
+ QString destsvn = ndest.url();
+
+ recordCurrentURL( nsrc );
+
+ //find the requested revision
+ svn_opt_revision_t rev;
+ int idx = srcsvn.findRev( "?rev=" );
+ if ( idx != -1 ) {
+ QString revstr = srcsvn.mid( idx+5 );
+ kdDebug(9036) << "revision string found " << revstr << endl;
+ if ( revstr == "HEAD" ) {
+ rev.kind = svn_opt_revision_head;
+ kdDebug(9036) << "revision searched : HEAD" << endl;
+ } else {
+ rev.kind = svn_opt_revision_number;
+ rev.value.number = revstr.toLong();
+ kdDebug(9036) << "revision searched : " << rev.value.number << endl;
+ }
+ srcsvn = srcsvn.left( idx );
+ kdDebug(9036) << "new src : " << srcsvn << endl;
+ } else {
+ kdDebug(9036) << "no revision given. searching HEAD " << endl;
+ rev.kind = svn_opt_revision_head;
+ }
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_move(&commit_info, srcsvn.utf8(), &rev, destsvn.utf8(), false/*force remove locally modified files in wc*/, ctx, subpool);
+ if ( err ) {
+ error( KIO::ERR_CANNOT_RENAME, err->message );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::special( const QByteArray& data ) {
+// kdDebug(9036) << "kio_svnProtocol::special" << endl;
+
+ QDataStream stream(data, IO_ReadOnly);
+ int tmp;
+
+ stream >> tmp;
+ kdDebug(9036) << "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(9036) << "kio_svnProtocol CHECKOUT from " << repository.url() << " to " << wc.url() << " at " << revnumber << " or " << revkind << endl;
+ checkout( repository, wc, revnumber, revkind );
+ break;
+ }
+ case SVN_UPDATE:
+ {
+ KURL::List list;
+ int revnumber;
+ QString revkind;
+ stream >> list;
+ stream >> revnumber;
+ stream >> revkind;
+ kdDebug(9036) << "kio_svnProtocol UPDATE " << endl;
+ update( list, revnumber, revkind );
+ break;
+ }
+ case SVN_COMMIT:
+ {
+ KURL::List wclist;
+ while ( !stream.atEnd() ) {
+ KURL tmp;
+ stream >> tmp;
+ wclist << tmp;
+ }
+ kdDebug(9036) << "kio_svnProtocol COMMIT" << endl;
+ commit( wclist );
+ break;
+ }
+ case SVN_COMMIT_2:
+ {
+ bool recurse, keeplocks;
+ KURL::List wclist;
+ stream >> recurse;
+ stream >> keeplocks;
+ while ( !stream.atEnd() ) {
+ KURL tmp;
+ stream >> tmp;
+ wclist << tmp;
+ }
+ kdDebug(9036) << "kio_svnProtocol COMMIT2" << endl;
+ commit2( recurse, keeplocks, wclist );
+ break;
+ }
+ case SVN_LOG:
+ {
+ kdDebug(9036) << "kio_svnProtocol LOG" << endl;
+ int revstart, revend;
+ QString revkindstart, revkindend;
+ bool discorverChangedPath, strictNodeHistory;
+ KURL::List targets;
+
+ stream >> revstart;
+ stream >> revkindstart;
+ stream >> revend;
+ stream >> revkindend;
+ stream >> discorverChangedPath;
+ stream >> strictNodeHistory;
+ while ( !stream.atEnd() ) {
+ KURL tmp;
+ stream >> tmp;
+ targets << tmp;
+ }
+ svn_log( revstart, revkindstart, revend, revkindend,
+ discorverChangedPath, strictNodeHistory, targets );
+ break;
+ }
+ case SVN_IMPORT:
+ {
+ KURL wc,repos;
+ stream >> repos;
+ stream >> wc;
+ kdDebug(9036) << "kio_svnProtocol IMPORT" << endl;
+ import(repos,wc);
+ break;
+ }
+ case SVN_ADD:
+ {
+ KURL::List wcList;
+ stream >> wcList;
+ kdDebug(9036) << "kio_svnProtocol ADD" << endl;
+ add(wcList);
+ break;
+ }
+ case SVN_DEL:
+ {
+ KURL::List wclist;
+ stream >> wclist;
+ kdDebug(9036) << "kio_svnProtocol DEL" << endl;
+ wc_delete(wclist);
+ break;
+ }
+ case SVN_REVERT:
+ {
+ KURL::List wclist;
+ stream >> wclist;
+ kdDebug(9036) << "kio_svnProtocol REVERT" << endl;
+ wc_revert(wclist);
+ break;
+ }
+ case SVN_STATUS:
+ {
+ KURL wc;
+ bool checkRepos=false;
+ bool fullRecurse=false;
+ stream >> wc;
+ stream >> checkRepos;
+ stream >> fullRecurse;
+ wc_status(wc,checkRepos,fullRecurse);
+ break;
+ }
+ case SVN_STATUS_2:
+ {
+ KURL wc;
+ QString revkind;
+ int revnumber;
+ bool checkRepos, fullRecurse, getAll, noIgnore;
+ stream >> checkRepos;
+ stream >> fullRecurse;
+ stream >> getAll;
+ stream >> noIgnore;
+ stream >> revnumber;
+ stream >> revkind;
+ stream >> wc;
+ wc_status2(wc,checkRepos,fullRecurse, getAll, noIgnore, revnumber, revkind);
+ break;
+ }
+ case SVN_MKDIR:
+ {
+ KURL::List list;
+ stream >> list;
+ kdDebug(9036) << "kio_svnProtocol MKDIR" << endl;
+ mkdir(list,0);
+ break;
+ }
+ case SVN_RESOLVE:
+ {
+ KURL url;
+ bool recurse;
+ stream >> url;
+ stream >> recurse;
+ kdDebug(9036) << "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(9036) << "kio_svnProtocol SWITCH" << endl;
+ svn_switch(wc,url,revnumber,revkind,recurse);
+ break;
+ }
+ case SVN_SWITCH_RELOCATE:
+ {
+ KURL wc, origUrl, newUrl;
+ bool recurse;
+ stream >> wc;
+ stream >> origUrl;
+ stream >> newUrl;
+ stream >> recurse;
+ svn_switch_relocate( wc, origUrl, newUrl, recurse );
+ break;
+ }
+ case SVN_DIFF:
+ {
+ KURL url1,url2;
+ int rev1, rev2;
+ bool recurse, pegdiff;
+ QString revkind1, revkind2;
+ stream >> url1;
+ stream >> url2;
+ stream >> rev1;
+ stream >> revkind1;
+ stream >> rev2;
+ stream >> revkind2;
+ stream >> recurse >> pegdiff;
+ kdDebug(9036) << "kio_svnProtocol DIFF" << endl;
+ svn_diff(url1,url2,rev1,rev2,revkind1,revkind2,recurse,pegdiff);
+ break;
+ }
+ case SVN_BLAME:
+ {
+ KURL url;
+ int urlMode;
+ int pegRev, startRev, endRev;
+ QString pegRevKind, startRevKind, endRevKind;
+ stream >> url;
+ stream >> urlMode;
+// stream >> pegRev;
+// stream >> pegRevKind;
+ stream >> startRev;
+ stream >> startRevKind;
+ stream >> endRev;
+ stream >> endRevKind;
+
+ blame(url, (UrlMode)urlMode, startRev, startRevKind, endRev, endRevKind);
+ break;
+ }
+ case SVN_INFO:
+ {
+ KURL pathOrUrl;
+ int pegRev, rev;
+ QString pegRevKind, revKind;
+ bool recurse = false;
+ stream >> pathOrUrl;
+ stream >> pegRev;
+ stream >> pegRevKind;
+ stream >> rev;
+ stream >> revKind;
+ stream >> recurse;
+ svn_info( pathOrUrl, pegRev, pegRevKind, rev, revKind, recurse );
+ break;
+ }
+ case SVN_COPY:
+ {
+ KURL src, dest;
+ int srcRev;
+ QString srcRevKind;
+ stream >> src;
+ stream >> srcRev;
+ stream >> srcRevKind;
+ stream >> dest;
+ svn_copy( src, srcRev, srcRevKind, dest );
+ break;
+ }
+ case SVN_MERGE:
+ {
+ KURL src1, src2, wc_target;
+ int rev1, rev2;
+ QString revKind1, revKind2;
+ bool recurse, ignore_ancestry, force, dry_run;
+ stream >> src1 >> rev1 >> revKind1;
+ stream >> src2 >> rev2 >> revKind2;
+ stream >> wc_target;
+ stream >> recurse >> ignore_ancestry >> force >> dry_run;
+ svn_merge( src1, rev1, revKind1, src2, rev2, revKind2, wc_target,
+ recurse, ignore_ancestry, force, dry_run );
+ break;
+ }
+ default:
+ {
+ kdDebug(9036) << "kio_svnProtocol DEFAULT" << endl;
+ break;
+ }
+ }
+}
+/**
+ * not used anywhere, anymore
+*/
+void kio_svnProtocol::popupMessage( const QString& message ) {
+// QByteArray params;
+// QDataStream stream(params, IO_WriteOnly);
+// stream << message;
+//
+// if ( !dcopClient()->send( "kded","ksvnd","popupMessage(QString)", params ) )
+// kdWarning() << "Communication with KDED:KSvnd failed" << endl;
+}
+
+void kio_svnProtocol::blame( KURL url, UrlMode /*mode*/,/* int pegRev, QString pegRevKind,*/ int startRev, QString startRevKind, int endRev, QString endRevKind )
+{
+ kdDebug(9036) << " __TIME__ " << __TIME__ << endl;
+// kdDebug(9036) << " PegRev " << pegRev << pegRevKind << endl;
+ kdDebug(9036) << " StartRev" << startRev << startRevKind << endl;
+ kdDebug(9036) << " EndRev" << endRev << endRevKind << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ const char* path_or_url = apr_pstrdup( subpool, url.pathOrURL().utf8() );;
+
+ svn_opt_revision_t rev1 = createRevision( startRev, startRevKind, subpool );
+ svn_opt_revision_t rev2 = createRevision( endRev, endRevKind, subpool );
+// svn_opt_revision_t revPeg = createRevision( pegRev, pegRevKind, subpool );
+
+ //initNotifier(false, false, false, subpool);
+ svn_client_blame_receiver_t receiver = kio_svnProtocol::blameReceiver;
+ svn_error_t *err = svn_client_blame( path_or_url, &rev1, &rev2, receiver, (void*)this, ctx, subpool );
+ if ( err )
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) );
+ finished();
+ svn_pool_destroy (subpool);
+
+}
+
+svn_error_t* kio_svnProtocol::blameReceiver( void *baton, apr_int64_t line_no, svn_revnum_t rev, const char *author, const char *date, const char *line, apr_pool_t *pool )
+{
+ kio_svnProtocol *p = (kio_svnProtocol*)baton;
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "LINE", QString::number(line_no) );
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "REV", QString::number(rev) );
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "AUTHOR", author );
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "DATE", date );
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "CONTENT", QString::fromLocal8Bit(line) );
+
+ p->incCounter();
+ return SVN_NO_ERROR;
+}
+
+/**
+ KDevelop has no way to retrieve URL of working copy.
+ Thus retreiving URL from WC should be done here, using subversion native API.
+ Thus, svn_log should get another flag (bool repositHistory )specifying between file:/// or URL
+*/
+void kio_svnProtocol::svn_log( int revstart, const QString& revkindstart, int revend, const QString& revkindend,
+ bool discorverChangedPaths, bool strictNodeHistory,
+ const KURL::List& urls )
+{
+// kdDebug(9036) << " from revision " << revstart << " or " << revkindstart << " to " << " revision " << revend << " or " << revkindend << endl;
+ kdDebug(9036) << " __TIME__ " << __TIME__ << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+
+ // TODO HEAD:1 was removed from SVN API 1.2, instead callers should specify HEAD:0
+ svn_opt_revision_t rev1 = createRevision( revstart, revkindstart, subpool );
+ svn_opt_revision_t rev2 = createRevision( revend, revkindend, subpool );
+
+ m_counter = 0;
+ apr_array_header_t *targets = apr_array_make(subpool, 1+urls.count(), sizeof(const char *));
+
+ for ( QValueListConstIterator<KURL> it = urls.begin(); it != urls.end() ; ++it ) {
+ KURL nurl = *it;
+ const char *path =
+ apr_pstrdup( subpool, svn_path_canonicalize( nurl.pathOrURL().utf8(), subpool ) );
+ kdDebug(9036) << path << endl;
+ *(( const char ** )apr_array_push(( apr_array_header_t* )targets)) = path;
+
+ setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "requrl", nurl.pathOrURL() );
+ incCounter();
+ }
+
+ svn_log_message_receiver_t receiver = kio_svnProtocol::receiveLogMessage;
+ svn_error_t *err = svn_client_log2(targets, &rev1, &rev2, 0, discorverChangedPaths, strictNodeHistory, receiver, this, ctx, subpool);
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+// save for one revision
+svn_error_t* kio_svnProtocol::receiveLogMessage(void *baton, apr_hash_t *changed_paths, svn_revnum_t revision,
+ const char *author, const char *date, const char *message, apr_pool_t *pool )
+{
+ kio_svnProtocol *p = (kio_svnProtocol*)baton;
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "rev", QString::number(revision) );
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "author", author );
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "date", date );
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "logmsg", QString::fromLocal8Bit(message) );
+ if( changed_paths != NULL ){
+ QString pathlist;
+ void *onePath;
+ const char *pathkey;
+ apr_hash_index_t *hi;
+ for (hi = apr_hash_first(pool, changed_paths); hi; hi = apr_hash_next(hi)) {
+ apr_hash_this(hi, (const void**) &pathkey, NULL, &onePath);
+ svn_log_changed_path_t *cp = (svn_log_changed_path_t*)onePath;
+ kdDebug(9036) << "OnePath: " << cp->copyfrom_path << " and key: " << pathkey << endl;
+ pathlist += cp->action;
+ pathlist += " ";
+// pathlist += cp->copyfrom_path;
+ pathlist += pathkey;
+ pathlist += "\n";
+ }
+ kdDebug(9036) << "pathlist: " << pathlist <<endl;
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "pathlist", pathlist );
+ }
+ p->incCounter();
+ return SVN_NO_ERROR;
+}
+
+svn_opt_revision_t kio_svnProtocol::createRevision( int revision, const QString& revkind, apr_pool_t *pool ) {
+ svn_opt_revision_t result;//,endrev;
+ // TODO support svn_opt_revision_date
+ if ( revision != -1 ) {
+ result.value.number = revision;
+ result.kind = svn_opt_revision_number;
+ } else if ( revkind == "WORKING" ) {
+ result.kind = svn_opt_revision_working;
+ } else if ( revkind == "BASE" ) {
+ result.kind = svn_opt_revision_base;
+ } else if ( revkind == "HEAD" ) {
+ result.kind = svn_opt_revision_head;
+ } else if ( revkind == "COMMITTED" ) {
+ result.kind = svn_opt_revision_committed;
+ } else if ( revkind == "PREV" ) {
+ result.kind = svn_opt_revision_previous;
+ }
+// } else if ( !revkind.isNull() ) {
+// svn_opt_parse_revision(&result,&endrev,revkind.utf8(),pool);
+ else if ( revkind == "UNSPECIFIED" ){
+ result.kind = svn_opt_revision_unspecified;
+ }
+ else {
+ result.kind = svn_opt_revision_unspecified;
+ }
+ return result;
+}
+
+void kio_svnProtocol::svn_diff(const KURL & url1, const KURL& url2,int rev1, int rev2,const QString& revkind1,const QString& revkind2,bool recurse, bool pegdiff )
+{
+ kdDebug(9036) << "kio_svn::diff : " << url1.path() << " at revision " << rev1 << " or " << revkind1 << " with "
+ << url2.path() << " at revision " << rev2 << " or " << revkind2
+ << endl ;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ apr_array_header_t *options = svn_cstring_split( "", "\t\r\n", TRUE, subpool );
+
+// KURL nurl1 = url1;
+// KURL nurl2 = url2;
+// nurl1.setProtocol( chooseProtocol( url1.protocol() ) ); //svn+https -> https for eg
+// nurl2.setProtocol( chooseProtocol( url2.protocol() ) );
+// recordCurrentURL( nurl1 );
+// QString source = makeSvnURL( nurl1 );
+// QString target = makeSvnURL( nurl2 );
+
+// const char *path1 = svn_path_canonicalize( apr_pstrdup( subpool, source.utf8() ), subpool );
+// const char *path2 = svn_path_canonicalize( apr_pstrdup( subpool, target.utf8() ), subpool );
+
+ //remove file:/// so we can diff for working copies, needs a better check (so we support URL for file:/// _repositories_ )
+// if ( nurl1.protocol() == "file" ) {
+// path1 = svn_path_canonicalize( apr_pstrdup( subpool, nurl1.path().utf8() ), subpool );
+// }
+// if ( nurl2.protocol() == "file" ) {
+// path2 = svn_path_canonicalize( apr_pstrdup( subpool, nurl2.path().utf8() ), subpool );
+// }
+
+ // all the commentted codes above are redundancy. url1/url2 is only file:// , svn:// or https://
+ // svn+https etc. are not handed out here.
+ const char *path1 = apr_pstrdup( subpool, url1.pathOrURL().utf8() );
+ const char *path2 = apr_pstrdup( subpool, url2.pathOrURL().utf8() );;
+
+ kdDebug( 9036 ) << "1 : " << path1 << " 2: " << path2 << endl;
+
+ svn_opt_revision_t revision1,revision2;
+ revision1 = createRevision(rev1, revkind1, subpool);
+ revision2 = createRevision(rev2, revkind2, subpool);
+
+ char *templ;
+ templ = apr_pstrdup ( subpool, "/tmp/tmpfile_XXXXXX" );
+ apr_file_t *outfile = NULL;
+ apr_file_mktemp( &outfile, templ , APR_READ|APR_WRITE|APR_CREATE|APR_TRUNCATE, subpool );
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = 0;
+ if( pegdiff ){
+ svn_opt_revision_t peg_rev = createRevision(-1, "BASE", subpool );
+ err = svn_client_diff_peg( options, path1, &peg_rev, &revision1, &revision2,
+ recurse, false, false, outfile, NULL, ctx, subpool );
+ } else{
+ err = svn_client_diff( options, path1, &revision1, path2, &revision2, recurse,
+ false, false, outfile, NULL, ctx, subpool );
+ }
+
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+ //read the content of the outfile now
+ QStringList tmp;
+ apr_file_close(outfile);
+ QFile file(templ);
+ if ( file.open( IO_ReadOnly ) ) {
+ QTextStream stream( &file );
+ QString line;
+ while ( !stream.atEnd() ) {
+ line = stream.readLine();
+ tmp << line;
+ }
+ file.close();
+ }
+ for ( QStringList::Iterator itt = tmp.begin(); itt != tmp.end(); itt++ ) {
+ setMetaData(QString::number( m_counter ).rightJustify( 10,'0' )+ "diffresult", ( *itt ) );
+ m_counter++;
+ }
+ //delete temp file
+ file.remove();
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::svn_switch( const KURL& wc, const KURL& repos, int revnumber, const QString& revkind, bool recurse) {
+ kdDebug(9036) << "kio_svn::switch : " << wc.path() << " at revision " << revnumber << " or " << revkind << endl ;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+
+ KURL nurl = repos;
+ KURL dest = wc;
+ nurl.setProtocol( chooseProtocol( repos.protocol() ) );
+ dest.setProtocol( "file" );
+// recordCurrentURL( nurl );
+// QString source = dest.path();
+// QString target = makeSvnURL( repos );
+
+ const char *path = svn_path_canonicalize( apr_pstrdup( subpool, dest.path().utf8() ), subpool );
+ const char *url = svn_path_canonicalize( apr_pstrdup( subpool, nurl.url().utf8() ), subpool );
+ kdDebug(9036) << " WC path: " << path << " Repository URL: " << url << endl;
+
+ svn_opt_revision_t rev = createRevision( revnumber, revkind, subpool );
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_switch (NULL/*result revision*/, path, url, &rev, recurse, ctx, subpool);
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit( err->message ) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::svn_switch_relocate( const KURL &wc, const KURL &origUrl, const KURL &newUrl,
+ bool recurse )
+{
+ apr_pool_t *subpool = svn_pool_create( pool );
+
+ const char *wcPath = svn_path_canonicalize( apr_pstrdup( subpool, wc.path().utf8() ), subpool );
+ const char *fromUrl = apr_pstrdup( subpool, origUrl.url().utf8() );
+ const char *toUrl = apr_pstrdup( subpool, newUrl.url().utf8() );
+ kdDebug(9036) << " WC path: " << wcPath << " from: " << fromUrl << " to: " << toUrl << endl;
+
+ svn_error_t *err = svn_client_relocate( wcPath, fromUrl, toUrl, recurse, ctx, pool );
+
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit( err->message ) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+ m_counter = 0L;
+ setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "string",
+ QString("switched to %1").arg( toUrl ) );
+ finished();
+ svn_pool_destroy( subpool );
+}
+
+void kio_svnProtocol::update( const KURL::List &list, int revnumber, const QString& revkind ) {
+ kdDebug(9036) << "kio_svn::update : __TIME__" << __TIME__ << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+
+ apr_array_header_t *targets = apr_array_make(subpool, 1+list.count(), sizeof(const char *));
+ svn_opt_revision_t rev = createRevision( revnumber, revkind, subpool );
+
+ for( QValueList<KURL>::ConstIterator it = list.begin(); it != list.end(); ++it ){
+ KURL nurl = *it;
+ *( const char ** )apr_array_push(targets) = svn_path_canonicalize( nurl.path().utf8(), subpool );
+ }
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_update2( NULL, targets, &rev,
+ true/*recurse*/, false/*ignore_external*/,
+ ctx, subpool);
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::import( const KURL& repos, const KURL& wc ) {
+ kdDebug(9036) << "kio_svnProtocol::import() : " << wc.url() << " into " << repos.url() << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+// svn_client_commit_info_t *commit_info =
+// (svn_client_commit_info_t*) apr_palloc( subpool, sizeof(svn_client_commit_info_t) );
+ svn_commit_info_t *commit_info = svn_create_commit_info( subpool );
+ bool nonrecursive = false;
+
+ const char *path = apr_pstrdup( subpool, svn_path_canonicalize( wc.path().utf8(), subpool ) );
+ const char *url = apr_pstrdup( subpool, svn_path_canonicalize( repos.url().utf8(), subpool ) );
+
+ initNotifier(false, false, false, subpool);
+ kdDebug(9036) << " Executing import: " << path << " to " << url << endl;
+
+ svn_error_t *err = svn_client_import2(&commit_info, path, url, nonrecursive, false, ctx, subpool);
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ svn_pool_destroy (subpool);
+ finished();
+}
+
+void kio_svnProtocol::checkout( const KURL& repos, const KURL& wc, int revnumber, const QString& revkind ) {
+ kdDebug(9036) << "kio_svn::checkout : " << repos.url() << " into " << wc.path() << " at revision " << revnumber << " or " << revkind << endl ;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ KURL nurl = repos;
+ KURL dest = wc;
+ nurl.setProtocol( chooseProtocol( repos.protocol() ) );
+ dest.setProtocol( "file" );
+ QString target = makeSvnURL( repos );
+ recordCurrentURL( nurl );
+ QString dpath = dest.path();
+
+ //find the requested revision
+ svn_opt_revision_t rev = createRevision( revnumber, revkind, subpool );
+
+ initNotifier(true, false, false, subpool);
+ svn_error_t *err = svn_client_checkout (NULL/* rev actually checkedout */, svn_path_canonicalize( target.utf8(), subpool ), svn_path_canonicalize ( dpath.utf8(), subpool ), &rev, true, ctx, subpool);
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, err->message );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::commit(const KURL::List& wc)
+{
+ commit2(true, true, wc);
+}
+
+void kio_svnProtocol::commit2(bool recurse, bool keeplocks, const KURL::List& wc) {
+ kdDebug(9036) << "kio_svnProtocol::commit2() : " << wc << endl;
+ apr_pool_t *subpool = svn_pool_create (pool);
+ svn_client_commit_info_t *commit_info = NULL;
+
+ apr_array_header_t *targets = apr_array_make(subpool, 1+wc.count(), sizeof(const char *));
+
+ for ( QValueListConstIterator<KURL> it = wc.begin(); it != wc.end() ; ++it ) {
+ KURL nurl = *it;
+ nurl.setProtocol( "file" );
+ recordCurrentURL( nurl );
+ (*(( const char ** )apr_array_push(( apr_array_header_t* )targets)) ) = svn_path_canonicalize( nurl.path().utf8(), subpool );
+ }
+
+ initNotifier(false, false, false, subpool);
+ kdDebug(9036) << "recurse: " << recurse << " keeplocks: " << keeplocks <<endl;
+ svn_error_t *err = svn_client_commit2(&commit_info,targets,recurse,keeplocks,ctx,subpool);
+
+ if ( err ){
+ char errbuf[512];
+ svn_strerror(err->apr_err, errbuf, 512);
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) + "\n: " + QString::fromLocal8Bit(errbuf) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ if ( commit_info ) {
+ for ( QValueListConstIterator<KURL> it = wc.begin(); it != wc.end() ; ++it ) {
+ KURL nurl = *it;
+ nurl.setProtocol( "file" );
+
+ QString userstring = i18n ( "Nothing to commit." );
+ if ( SVN_IS_VALID_REVNUM( commit_info->revision ) )
+ userstring = i18n( "Committed revision %1." ).arg(commit_info->revision);
+ setMetaData(QString::number( m_counter ).rightJustify( 10,'0' )+ "path", nurl.path() );
+ setMetaData(QString::number( m_counter ).rightJustify( 10,'0' )+ "action", "0" );
+ setMetaData(QString::number( m_counter ).rightJustify( 10,'0' )+ "kind", "0" );
+ setMetaData(QString::number( m_counter ).rightJustify( 10,'0' )+ "mime_t", "" );
+ setMetaData(QString::number( m_counter ).rightJustify( 10,'0' )+ "content", "0" );
+ setMetaData(QString::number( m_counter ).rightJustify( 10,'0' )+ "prop", "0" );
+ setMetaData(QString::number( m_counter ).rightJustify( 10,'0' )+ "rev" , QString::number( commit_info->revision ) );
+ setMetaData(QString::number( m_counter ).rightJustify( 10,'0' )+ "string", userstring );
+ m_counter++;
+ }
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::add(const KURL::List& list) {
+ kdDebug(9036) << "kio_svnProtocol::add() __TIME__" << __TIME__ << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ bool nonrecursive = false;
+ initNotifier(false, false, false, subpool);
+
+ svn_error_t *err = NULL;
+ for( QValueList<KURL>::ConstIterator it = list.begin(); it != list.end(); ++it ){
+
+ KURL nurl = (*it);
+ nurl.setProtocol( "file" );
+ recordCurrentURL( nurl );
+ kdDebug(9036) << " Schedule to Add: " << nurl.path().utf8() << endl;
+ err = svn_client_add( svn_path_canonicalize( nurl.path().utf8(), subpool ),
+ nonrecursive, ctx, subpool);
+ if( err ) break;
+ }
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::wc_delete(const KURL::List& wc) {
+ kdDebug(9036) << "kio_svnProtocol::wc_delete() : " << wc << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ svn_client_commit_info_t *commit_info = NULL;
+ bool force = false;
+
+ apr_array_header_t *targets = apr_array_make(subpool, 1+wc.count(), sizeof(const char *));
+
+ for ( QValueListConstIterator<KURL> it = wc.begin(); it != wc.end() ; ++it ) {
+ KURL nurl = *it;
+ nurl.setProtocol( "file" );
+ recordCurrentURL( nurl );
+ (*(( const char ** )apr_array_push(( apr_array_header_t* )targets)) ) = svn_path_canonicalize( nurl.path().utf8(), subpool );
+ }
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_delete(&commit_info,targets,force,ctx,subpool);
+
+ if ( err )
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) );
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::wc_revert(const KURL::List& wc) {
+ kdDebug(9036) << "kio_svnProtocol::revert() : " << wc << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ bool nonrecursive = false;
+
+ apr_array_header_t *targets = apr_array_make(subpool, 1 + wc.count(), sizeof(const char *));
+
+ for ( QValueListConstIterator<KURL> it = wc.begin(); it != wc.end() ; ++it ) {
+ KURL nurl = *it;
+ nurl.setProtocol( "file" );
+ recordCurrentURL( nurl );
+ (*(( const char ** )apr_array_push(( apr_array_header_t* )targets)) ) = svn_path_canonicalize( nurl.path().utf8(), subpool );
+ }
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_revert(targets,nonrecursive,ctx,subpool);
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit( err->message ) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::wc_status(const KURL& wc, bool checkRepos, bool fullRecurse, bool getAll, int revnumber, const QString& revkind) {
+ kdDebug(9036) << "kio_svnProtocol::wc_status() : " << wc.url() << " checkRepos " << checkRepos << " fullRecurse " << fullRecurse << " getAll " << getAll << endl;
+
+ wc_status2( wc, checkRepos, fullRecurse, getAll, false, revnumber, revkind );
+}
+
+void kio_svnProtocol::wc_status2(const KURL& wc, bool checkRepos, bool fullRecurse, bool getAll, bool noIgnore, int revnumber, const QString& revkind) {
+ kdDebug(9036) << "kio_svnProtocol::wc_status2() : " << wc.url() << " checkRepos " << checkRepos << " fullRecurse " << fullRecurse << " getAll " << getAll << " noIgnore " << noIgnore << " revnumber " << revnumber << " revkind " << revkind << endl;
+ kdDebug(9036) << " __TIME__ " << __TIME__ << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ svn_revnum_t result_rev;
+
+ KURL nurl = wc;
+ nurl.setProtocol( "file" );
+ recordCurrentURL( nurl );
+
+ svn_opt_revision_t rev = createRevision( revnumber, revkind, subpool );
+
+ initNotifier(false, false, false, subpool);
+
+ svn_error_t *err = svn_client_status(&result_rev, svn_path_canonicalize( nurl.path().utf8(), subpool ), &rev, kio_svnProtocol::status, this, fullRecurse, getAll, checkRepos, noIgnore, ctx, subpool);
+
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::svn_info( KURL pathOrUrl, int pegRev, QString pegRevKind, int rev, QString revKind, bool recurse )
+{
+ kdDebug(9036) << " kio_svnProtocol::svn_info(): pegRev " << pegRev << " pegKind " << pegRevKind << " rev " << rev << " revKind " << revKind << " recurse " << recurse << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+ svn_opt_revision_t peg_rev = createRevision( pegRev, pegRevKind, subpool );
+ svn_opt_revision_t revision = createRevision( rev, revKind, subpool );
+
+ svn_error_t *err = svn_client_info( pathOrUrl.pathOrURL().utf8(),
+ &peg_rev, &revision,
+ kio_svnProtocol::infoReceiver,
+ this,
+ recurse,
+ ctx, pool );
+
+ if ( err ){
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(err->message) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+ svn_pool_destroy( subpool );
+ finished();
+}
+
+svn_error_t* kio_svnProtocol::infoReceiver( void *baton, const char *path,
+ const svn_info_t *info, apr_pool_t *pool)
+{
+ kio_svnProtocol *p= (kio_svnProtocol*)baton ;
+ if( !p )
+ return SVN_NO_ERROR;
+
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "PATH", QString::fromUtf8( path ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "URL", QString( info->URL ) );
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "REV", QString::number( info->rev ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "KIND", QString::number( info->kind ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "REPOS_ROOT_URL", QString( info->repos_root_URL ) );
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "REPOS_UUID", QString(info->repos_UUID) );
+ p->incCounter();
+
+ return SVN_NO_ERROR;
+}
+
+void kio_svnProtocol::svn_copy( const KURL &srcUrl, int srcRev, const QString &srcRevKind,
+ const KURL &destUrl )
+{
+ kdDebug(9036) << " kio: svn_copy src: " << srcUrl << " Dest Url: " << destUrl << " revnum: " << srcRev << " revKind: " << srcRevKind << endl;
+ apr_pool_t *subpool = svn_pool_create (pool);
+ svn_commit_info_t *commit_info = svn_create_commit_info( subpool );
+
+ svn_opt_revision_t rev = createRevision( srcRev, srcRevKind, subpool );
+
+ // TODO more elegant notification mechanism
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_copy2( &commit_info,
+ srcUrl.pathOrURL().utf8(), &rev,
+ destUrl.pathOrURL().utf8(),
+ ctx, subpool);
+
+ if ( err ) {
+ apr_status_t errcode = err->apr_err;
+ char buf[512];
+ svn_strerror(errcode, buf, 512);
+ error( KIO::ERR_SLAVE_DEFINED, QString::fromLocal8Bit(buf) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ if( commit_info ){
+ setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "string",
+ i18n("Copied Revision %1").arg( commit_info->revision) );
+ } else {
+ setMetaData(QString::number( counter() ).rightJustify( 10,'0' )+ "string",
+ i18n("Copied") );
+ }
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+void kio_svnProtocol::svn_merge(const KURL &src1, int revNum1, QString revKind1,
+ const KURL &src2, int revNum2, QString revKind2,
+ const KURL &target_wc,
+ bool recurse, bool ignore_ancestry, bool force, bool dry_run )
+{
+ kdDebug(9036) << " KIO::svn_merge src1 " << src1.pathOrURL().utf8() << " src2 " << src2.pathOrURL().utf8() << " target " << target_wc.pathOrURL().utf8() << endl;
+ apr_pool_t *subpool = svn_pool_create( pool );
+
+ svn_opt_revision_t rev1 = createRevision( revNum1, revKind1, subpool );
+ svn_opt_revision_t rev2 = createRevision( revNum2, revKind2, subpool );
+
+ initNotifier( false, false, false, subpool );
+ svn_error_t *err = svn_client_merge( src1.pathOrURL().utf8(), &rev1,
+ src2.pathOrURL().utf8(), &rev2,
+ target_wc.pathOrURL().utf8(),
+ recurse, ignore_ancestry, force, dry_run,
+ ctx, pool );
+ if ( err ) {
+ apr_status_t errcode = err->apr_err;
+ char buf[512];
+ svn_strerror(errcode, buf, 512);
+ error( KIO::ERR_SLAVE_DEFINED,
+ QString::fromLocal8Bit(err->message) + "\n "+ QString::fromLocal8Bit(buf) );
+ svn_pool_destroy (subpool);
+ return;
+ }
+
+ finished();
+ svn_pool_destroy( subpool );
+}
+
+//change the proto and remove trailing /
+//remove double / also
+QString kio_svnProtocol::makeSvnURL ( const KURL& url ) const {
+ QString kproto = url.protocol();
+ KURL tpURL = url;
+ tpURL.cleanPath( true );
+ QString svnUrl;
+ if ( kproto == "kdevsvn+http" ) {
+ kdDebug(9036) << "http:/ " << url.url() << endl;
+ tpURL.setProtocol("http");
+ svnUrl = tpURL.url(-1);
+ return svnUrl;
+ }
+ else if ( kproto == "kdevsvn+https" ) {
+ kdDebug(9036) << "https:/ " << url.url() << endl;
+ tpURL.setProtocol("https");
+ svnUrl = tpURL.url(-1);
+ return svnUrl;
+ }
+ else if ( kproto == "kdevsvn+ssh" ) {
+ kdDebug(9036) << "svn+ssh:/ " << url.url() << endl;
+ tpURL.setProtocol("svn+ssh");
+ svnUrl = tpURL.url(-1);
+ return svnUrl;
+ }
+ else if ( kproto == "kdevsvn+svn" ) {
+ kdDebug(9036) << "svn:/ " << url.url() << endl;
+ tpURL.setProtocol("svn");
+ svnUrl = tpURL.url(-1);
+ return svnUrl;
+ }
+ else if ( kproto == "kdevsvn+file" ) {
+ kdDebug(9036) << "file:/ " << url.url() << endl;
+ tpURL.setProtocol("file");
+ svnUrl = tpURL.url(-1);
+ //hack : add one more / after file:/
+ int idx = svnUrl.find("/");
+ svnUrl.insert( idx, "//" );
+ return svnUrl;
+ }
+ return tpURL.url(-1);
+}
+
+QString kio_svnProtocol::chooseProtocol ( const QString& kproto ) const {
+ if ( kproto == "svn+http" ) return QString( "http" );
+ else if ( kproto == "svn+https" ) return QString( "https" );
+ else if ( kproto == "svn+ssh" ) return QString( "svn+ssh" );
+ else if ( kproto == "svn" ) return QString( "svn" );
+ else if ( kproto == "svn+file" ) return QString( "file" );
+ return kproto;
+}
+/** Certificate is not yet valid. */
+#define SVN_AUTH_SSL_NOTYETVALID 0x00000001
+/** Certificate has expired. */
+#define SVN_AUTH_SSL_EXPIRED 0x00000002
+/** Certificate's CN (hostname) does not match the remote hostname. */
+#define SVN_AUTH_SSL_CNMISMATCH 0x00000004
+/** @brief Certificate authority is unknown (i.e. not trusted) */
+#define SVN_AUTH_SSL_UNKNOWNCA 0x00000008
+/** @brief Other failure. This can happen if neon has introduced a new
+ * failure bit that we do not handle yet. */
+#define SVN_AUTH_SSL_OTHER 0x40000000
+svn_error_t *kio_svnProtocol::trustSSLPrompt(svn_auth_cred_ssl_server_trust_t **cred_p, void *baton, const char *realm, apr_uint32_t failures, const svn_auth_ssl_server_cert_info_t *ci, svn_boolean_t may_save, apr_pool_t *pool)
+{
+ kio_svnProtocol *p = (kio_svnProtocol*)baton;
+ // prepare params.
+ QByteArray params, replyData;
+ QCString replyType;
+ QDataStream arg(params, IO_WriteOnly);
+
+ arg << i18n( "The certificate from the server could not be trusted automatically. Do you want to trust this certificate? " );
+ arg << QString::fromLocal8Bit(ci->hostname);
+ arg << QString::fromLocal8Bit(ci->fingerprint);
+ arg << QString::fromLocal8Bit(ci->valid_from) << QString::fromLocal8Bit(ci->valid_until);
+ arg << QString::fromLocal8Bit(ci->issuer_dname) << QString::fromLocal8Bit(ci->ascii_cert) ;
+ // call dcop
+ int ret = p->dcopClient()->call( "kded", "kdevsvnd",
+ "sslServerTrustPrompt(QString, QString, QString, QString, QString, QString, QString)",
+ params, replyType, replyData );
+ if (!ret){
+ kdWarning() << " failed to prompt SSL_Server_Trust_Prompt " << endl;
+ return SVN_NO_ERROR;
+ }
+ if (replyType != "int"){
+ kdWarning() << " abnormal reply type " << endl;
+ return SVN_NO_ERROR;
+ }
+ int resultCode;
+ QDataStream replyStream( replyData, IO_ReadOnly );
+ replyStream >> resultCode;
+
+ if( resultCode == -1 ){
+ kdWarning() << " SSL server trust rejected " << endl;
+ *cred_p = 0L; //FIXME when rejected, maybe more elegant methods..
+ } else if( resultCode == 0 ){ //accept once
+ *cred_p = (svn_auth_cred_ssl_server_trust_t*)apr_pcalloc (pool, sizeof (svn_auth_cred_ssl_server_trust_t));
+ kdDebug(9036) << " accept once " << endl;
+ (*cred_p)->may_save = false;
+ (*cred_p)->accepted_failures = 0;
+ } else if( resultCode == 1 ){ //accept permanently
+ *cred_p = (svn_auth_cred_ssl_server_trust_t*)apr_pcalloc (pool, sizeof (svn_auth_cred_ssl_server_trust_t));
+ kdDebug(9036) << " accept permanently " << endl;
+ (*cred_p)->may_save = true;
+ (*cred_p)->accepted_failures = failures;
+ } else{
+ kdWarning() << " SSL server trust failed for some reason" << endl;
+ *cred_p = 0L;
+ }
+
+ return SVN_NO_ERROR;
+}
+/** TODO fully implemented, but there is no way to test this yet.*/
+svn_error_t *kio_svnProtocol::clientCertSSLPrompt(
+ svn_auth_cred_ssl_client_cert_t **cred_p, void *baton, const char *realm, svn_boolean_t may_save, apr_pool_t *pool)
+{
+ kdDebug(9036) << " clientCertSSLPrompt " << endl;
+// kio_svnProtocol *p = (kio_svnProtocol*)baton;
+// QByteArray reply;
+// QByteArray params;
+// QCString replyType;
+// call dcop
+// if (!p->dcopClient()->call("kded","kdevsvnd", "sslCertFile()",params,replyType,reply)) {
+// kdWarning()<<" Communication with dcop failed - fail to get certfile "<<endl;
+// return SVN_NO_ERROR;
+// }
+// if (replyType != "QString") {
+// kdWarning()<<" unexpected reply type "<<endl;
+// return SVN_NO_ERROR;
+// }
+// save reply data
+// QString fileName;
+// QDataStream replyStream( reply, IO_ReadOnly );
+// replyStream >> fileName;
+// allocate memory
+// *cred_p = (svn_auth_cred_ssl_client_cert_t*) apr_palloc (pool, sizeof(svn_auth_cred_ssl_client_cert_t));
+// (*cred_p)->cert_file = apr_pstrdup( pool, fileName.utf8() );
+// (*cred_p)->may_save = may_save;
+ return SVN_NO_ERROR;
+}
+
+/** TODO fully implemented, but there is no way to test this yet.*/
+svn_error_t *kio_svnProtocol::clientCertPasswdPrompt(
+ svn_auth_cred_ssl_client_cert_pw_t **cred_p, void *baton, const char *realm, svn_boolean_t may_save, apr_pool_t *pool)
+{
+ kdDebug(9036) << " Password Prompt Callback " << endl;
+ kdDebug(9036) << " realm " << realm << " <--realm " << endl;
+// kio_svnProtocol *p = ( kio_svnProtocol* )baton;
+// // prepare dcop
+// QByteArray reply;
+// QByteArray params;
+// QCString replyType;
+// QDataStream arg( params, IO_WriteOnly );
+// arg << i18n( "Enter password for subversion repository access" ) + "\n" + QString(realm);
+// // call dcop
+// if (!p->dcopClient()->call("kded","kdevsvnd", "sslPasswdDlg(QString)",params,replyType,reply)) {
+// kdWarning()<<" Communication with dcop failed - fail to show passwd dlg"<<endl;
+// return SVN_NO_ERROR;
+// }
+// if (replyType != "QCString") {
+// kdWarning()<<" unexpected reply type "<<endl;
+// return SVN_NO_ERROR;
+// }
+// // save reply data
+// QCString retstr, passwd;
+// QDataStream replyStream( reply, IO_ReadOnly );
+// replyStream >> retstr;
+//
+// if( retstr.left(1) == "-1" ){
+// kdDebug(9036) << " Null string received for passwd " << endl;
+// } else{
+// passwd = retstr.right( retstr.length() - 1 );
+// kdDebug(9036) << " PassWD : " << passwd << endl;
+// }
+//
+// svn_auth_cred_ssl_client_cert_pw_t *newcred = (svn_auth_cred_ssl_client_cert_pw_t*) apr_palloc (pool, sizeof (svn_auth_cred_ssl_client_cert_pw_t ) );
+//
+// newcred->password = apr_pstrdup(pool, (const char*) passwd );
+// newcred->may_save = false;
+// *cred_p = newcred;
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *kio_svnProtocol::commitLogPrompt( const char **log_msg, const char **file,
+ apr_array_header_t *commit_items, void *baton, apr_pool_t *pool )
+{
+ *file = NULL; // if omitting this, it will segfault at import operation.
+ QCString replyType;
+ QByteArray params;
+ QByteArray reply;
+ QString result;// slist;
+ QStringList slist;
+ kio_svnProtocol *p = ( kio_svnProtocol* )baton;
+ svn_stringbuf_t *message = NULL;
+
+ for (int i = 0; i < commit_items->nelts; i++) {
+ QString list;
+ svn_client_commit_item_t *item = ((svn_client_commit_item_t **) commit_items->elts)[i];
+ const char *path = item->path;
+ char text_mod = '_', prop_mod = ' ';
+
+ if (! path)
+ path = item->url;
+ else if (! *path)
+ path = ".";
+
+ if (! path)
+ path = ".";
+
+ if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE) && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))
+ text_mod = 'R';
+ else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
+ text_mod = 'A';
+ else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
+ text_mod = 'D';
+ else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS)
+ text_mod = 'M';
+ if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)
+ prop_mod = 'M';
+
+ list += text_mod;
+ list += " ";
+ list += prop_mod;
+ list += " ";
+ list += path;
+ kdDebug(9036) << " Commiting items : " << list << endl;
+ slist << list;
+// slist += list;
+ }
+
+ QDataStream stream(params, IO_WriteOnly);
+ stream << slist.join("\n");
+
+ kdDebug(9036) << " __TIME__ " << __TIME__ << endl;
+ if ( !p->dcopClient()->call( "kded","kdevsvnd","commitDialog(QString)", params, replyType, reply ) ) {
+ kdWarning() << "Communication with KDED:KDevSvnd failed" << endl;
+ svn_error_t *err = svn_error_create( SVN_ERR_EXTERNAL_PROGRAM, NULL,
+ apr_pstrdup( pool, "Fail to call kded_kdevsvnd via DCOP. If this is your first problem, try to restart KDE" ) );
+ return err;
+ }
+
+ if ( replyType != "QString" ) {
+ kdWarning() << "Unexpected reply type" << endl;
+ svn_error_t *err = svn_error_create( SVN_ERR_EXTERNAL_PROGRAM, NULL,
+ apr_pstrdup( pool, "Fail to call kded_kdevsvnd via DCOP." ) );
+ return err;
+ }
+
+ QDataStream stream2 ( reply, IO_ReadOnly );
+ stream2 >> result;
+
+ if ( result.isNull() ) { //cancelled
+ *log_msg = NULL;
+ svn_error_t *err = svn_error_create( SVN_ERR_CANCELLED, NULL,
+ apr_pstrdup( pool, "Commit interruppted" ) );
+ return err;
+ }
+
+ message = svn_stringbuf_create( result.utf8(), pool );
+ *log_msg = message->data;
+
+ return SVN_NO_ERROR;
+}
+
+void kio_svnProtocol::notify(void *baton, 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) {
+ kdDebug(9036) << "NOTIFY : " << path << " updated at revision " << revision << " action : " << action << ", kind : " << kind << " , content_state : " << content_state << ", prop_state : " << prop_state << endl;
+
+ QString userstring;
+ struct notify_baton *nb = ( struct notify_baton* ) baton;
+
+ //// Convert notification to a user readable string
+ switch ( action ) {
+ case svn_wc_notify_add : //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;
+ case svn_wc_notify_copy: //copy
+ userstring = i18n( "Copied %1 " ).arg( path );
+ break;
+ case svn_wc_notify_delete: //delete
+ nb->received_some_change = 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
+ nb->received_some_change = TRUE;
+ userstring=i18n( "D %1" ).arg( path );
+ break;
+ case svn_wc_notify_update_add: //update_add
+ nb->received_some_change = 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)))) {
+ nb->received_some_change = 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 (! nb->suppress_final_line) {
+ if (SVN_IS_VALID_REVNUM (revision)) {
+ if (nb->is_export) {
+ if ( nb->in_external )
+ userstring = i18n("Exported external at revision %1.").arg( revision );
+ else
+ userstring = i18n("Exported revision %1.").arg( revision );
+ } else if (nb->is_checkout) {
+ if ( nb->in_external )
+ userstring = i18n("Checked out external at revision %1.").arg( revision );
+ else
+ userstring = i18n("Checked out revision %1.").arg( revision);
+ } else {
+ if (nb->received_some_change) {
+ if ( nb->in_external )
+ userstring=i18n("Updated external to revision %1.").arg( revision );
+ else
+ userstring = i18n("Updated to revision %1.").arg( revision);
+ } else {
+ if ( nb->in_external )
+ userstring = i18n("External at revision %1.").arg( revision );
+ else
+ userstring = i18n("At revision %1.").arg( revision);
+ }
+ }
+ } else /* no revision */ {
+ if (nb->is_export) {
+ if ( nb->in_external )
+ userstring = i18n("External export complete.");
+ else
+ userstring = i18n("Export complete.");
+ } else if (nb->is_checkout) {
+ if ( nb->in_external )
+ userstring = i18n("External checkout complete.");
+ else
+ userstring = i18n("Checkout complete.");
+ } else {
+ if ( nb->in_external )
+ userstring = i18n("External update complete.");
+ else
+ userstring = i18n("Update complete.");
+ }
+ }
+ }
+ }
+ if (nb->in_external)
+ nb->in_external = FALSE;
+ break;
+ case svn_wc_notify_update_external: //update_external
+ nb->in_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 (! nb->sent_first_txdelta) {
+ nb->sent_first_txdelta = TRUE;
+ userstring=i18n("Transmitting file data ");
+ } else {
+ userstring=".";
+ }
+ break;
+
+ break;
+ case svn_wc_notify_blame_revision: //blame_revision
+ userstring = i18n("Blame %1.").arg(path);
+ break;
+ default:
+ break;
+ }
+ //// End convert
+ kio_svnProtocol *p = ( kio_svnProtocol* )nb->master;
+ if (!p) kdDebug(9036) << " Null Pointer at Line " << __LINE__ << endl;
+
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "path" , QString::fromUtf8( path ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "action", QString::number( action ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "kind", QString::number( kind ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "mime_t", QString::fromUtf8( mime_type ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "content", QString::number( content_state ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "prop", QString::number( prop_state ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "rev", QString::number( revision ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "string", userstring );
+ kdDebug(9036) << " kio_svnProtocol::notify() userstring " << userstring << endl;
+ p->incCounter();
+}
+
+void kio_svnProtocol::status(void *baton, const char *path, svn_wc_status_t *status) {
+ kdDebug(9036) << "STATUS : " << path << ", wc text status : " << status->text_status
+ << ", wc prop status : " << status->prop_status
+ << ", repos text status : " << status->repos_text_status
+ << ", repos prop status : " << status->repos_prop_status
+ << endl;
+
+ QByteArray params;
+ kio_svnProtocol *p = ( kio_svnProtocol* )baton;
+
+ QDataStream stream(params, IO_WriteOnly);
+ long int rev = status->entry ? status->entry->revision : 0;
+ stream << QString::fromUtf8( path ) << status->text_status << status->prop_status << status->repos_text_status << status->repos_prop_status << rev;
+
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "path", QString::fromUtf8( path ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "text", QString::number( status->text_status ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "prop", QString::number( status->prop_status ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "reptxt", QString::number( status->repos_text_status ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "repprop", QString::number( status->repos_prop_status ));
+ p->setMetaData(QString::number( p->counter() ).rightJustify( 10,'0' )+ "rev", QString::number( rev ));
+ p->incCounter();
+}
+
+void kio_svnProtocol::progressCallback( apr_off_t processed, apr_off_t total, void *baton, apr_pool_t *pool)
+{
+ kio_svnProtocol *p = (kio_svnProtocol*)baton;
+ if( total > -1 )
+ p->totalSize( total );
+ if( processed > -1 )
+ p->processedSize( processed );
+}
+
+void kio_svnProtocol::wc_resolve( const KURL& wc, bool recurse ) {
+ kdDebug(9036) << "kio_svnProtocol::wc_resolve() : " << wc.url() << endl;
+
+ apr_pool_t *subpool = svn_pool_create (pool);
+
+ KURL nurl = wc;
+ nurl.setProtocol( "file" );
+ recordCurrentURL( nurl );
+
+ initNotifier(false, false, false, subpool);
+ svn_error_t *err = svn_client_resolved(svn_path_canonicalize( nurl.path().utf8(), subpool ), recurse,ctx,subpool);
+ if ( err )
+ error( KIO::ERR_SLAVE_DEFINED, err->message );
+
+ finished();
+ svn_pool_destroy (subpool);
+}
+
+extern "C"
+{
+ KDE_EXPORT int kdemain(int argc, char **argv) {
+ KInstance instance( "kio_kdevsvn" );
+
+ kdDebug(9036) << "*** Starting kio_kdevsvn " << endl;
+
+ if (argc != 4) {
+ kdDebug(9036) << "Usage: kio_kdevsvn protocol domain-socket1 domain-socket2" << endl;
+ exit(-1);
+ }
+
+ kio_svnProtocol slave(argv[2], argv[3]);
+ slave.dispatchLoop();
+
+ kdDebug(9036) << "*** kio_kdevsvn Done" << endl;
+ return 0;
+ }
+}
+
diff --git a/vcs/subversion/svn_kio.h b/vcs/subversion/svn_kio.h
new file mode 100644
index 00000000..6164488a
--- /dev/null
+++ b/vcs/subversion/svn_kio.h
@@ -0,0 +1,163 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Mickael Marchand <marchand@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef _svn_H_
+#define _svn_H_
+
+#include <qstring.h>
+#include <qcstring.h>
+
+#include <kurl.h>
+#include <kio/global.h>
+#include <kio/slavebase.h>
+#include <subversion-1/svn_pools.h>
+#include <subversion-1/svn_auth.h>
+#include <subversion-1/svn_client.h>
+#include <subversion-1/svn_config.h>
+#include <sys/stat.h>
+#include <qvaluelist.h>
+#include <subversion-1/svn_wc.h>
+#include "subversion_global.h"
+
+class QCString;
+class kio_svnProtocol;
+
+typedef struct kbaton {
+ svn_stream_t *target_stream;
+ svn_stringbuf_t *target_string;
+ svn_stream_t *string_stream;
+} kbaton;
+
+typedef struct kio_svn_callback_baton_t {
+ const char* base_dir;
+ apr_hash_t *config;
+ apr_pool_t *pool;
+} kio_svn_callback_baton_t;
+
+typedef struct notify_baton {
+ svn_boolean_t received_some_change;
+ svn_boolean_t is_checkout;
+ svn_boolean_t is_export;
+ svn_boolean_t suppress_final_line;
+ svn_boolean_t sent_first_txdelta;
+ svn_boolean_t in_external;
+ svn_boolean_t had_print_error; /* Used to not keep printing error messages
+ when we've already had one print error. */
+ apr_pool_t *pool; /* this pool is cleared after every notification,
+ so don't keep anything here! */
+ kio_svnProtocol *master;
+} notify_baton;
+
+
+class kio_svnProtocol : public KIO::SlaveBase
+{
+ public:
+ kio_svnProtocol(const QCString &pool_socket, const QCString &app_socket);
+ virtual ~kio_svnProtocol();
+ virtual void special( const QByteArray& data );
+ virtual void get(const KURL& url);
+ virtual void listDir(const KURL& url);
+ virtual void stat(const KURL& url);
+ virtual void mkdir(const KURL& url, int permissions);
+ virtual void mkdir(const KURL::List& list, int permissions);
+ virtual void del( const KURL& url, bool isfile );
+// virtual void copy(const KURL & src, const KURL& dest, int permissions, bool overwrite);
+ virtual void rename(const KURL& src, const KURL& dest, bool overwrite);
+ void checkout( const KURL& repos, const KURL& wc, int revnumber, const QString& revkind );
+ void import( const KURL& repos, const KURL& wc );
+ void svn_switch( const KURL& wc, const KURL& url, int revnumber, const QString& revkind, bool recurse);
+ void svn_switch_relocate( const KURL &wc, const KURL &origUrl, const KURL &newUrl,
+ bool recurse );
+ void svn_diff( const KURL& url1, const KURL& url2, int rev1, int rev2, const QString& revkind1, const QString& revkind2, bool recurse, bool pegdiff);
+ //TODO fix with svn 1.2 : support a KURL::List -> svn_client_update2()
+ void update( const KURL::List &list, int revnumber, const QString& revkind );
+ void commit( const KURL::List& wc );
+ void commit2( bool recurse, bool keeplocks, const KURL::List& wc );
+ void blame( KURL url, SvnGlobal::UrlMode mode, /*int pegRev, QString pegRevKind,*/ int startRev, QString startRevKind, int endRev, QString endRevKind );
+ static svn_error_t* blameReceiver( void *baton, apr_int64_t line_no, svn_revnum_t rev, const char *author, const char *date, const char *line, apr_pool_t *pool );
+ void svn_log( int revstart, const QString &revkindstart, int revend, const QString &revkindend, bool discorverChangedPath, bool strictNodeHistory, const KURL::List& targets );
+ static svn_error_t* receiveLogMessage(void *baton, apr_hash_t *changed_paths, svn_revnum_t revision, const char *author, const char *date, const char *message, apr_pool_t *pool );
+ void add( const KURL::List& wcList );
+ //these work using the working copy
+ void wc_resolve( const KURL& wc, bool recurse = true );
+ void wc_delete( const KURL::List& wc );
+ void wc_revert( const KURL::List& wc );
+ void wc_status(const KURL& wc, bool checkRepos=false, bool fullRecurse=true, bool getAll=true, int revnumber=-1, const QString& revkind="HEAD");
+ void wc_status2(const KURL& wc, bool checkRepos=false, bool fullRecurse=true, bool getAll=true, bool noIgnore=false, int revnumber=-1, const QString& revkind="WORKING");
+ void svn_info( KURL pathOrUrl, int pegRev, QString pegRevKind, int rev, QString revKind, bool recurse );
+ static svn_error_t* infoReceiver( void *baton, const char *path, const svn_info_t *info, apr_pool_t *pool);
+ void svn_copy( const KURL &srcUrl, int srcRev, const QString &srcRevKind, const KURL &destUrl );
+ void svn_merge( const KURL &src1, int rev1, QString revKind1, const KURL &src2, int rev2, QString revKind2,
+ const KURL &target_wc,
+ bool recurse, bool ignore_ancestry, bool force, bool dry_run );
+
+ static svn_error_t* checkAuth(svn_auth_cred_simple_t **cred, void *baton, const char *realm, const char *username, svn_boolean_t may_save, apr_pool_t *pool);
+ static svn_error_t *trustSSLPrompt(svn_auth_cred_ssl_server_trust_t **cred_p, void *, const char *realm, apr_uint32_t failures, const svn_auth_ssl_server_cert_info_t *cert_info, svn_boolean_t may_save, apr_pool_t *pool);
+ static svn_error_t *clientCertSSLPrompt(svn_auth_cred_ssl_client_cert_t **cred_p, void *, const char *realm, svn_boolean_t may_save, apr_pool_t *pool);
+ static svn_error_t *clientCertPasswdPrompt(svn_auth_cred_ssl_client_cert_pw_t **cred_p, void *, const char *realm, svn_boolean_t may_save, apr_pool_t *pool);
+ static svn_error_t *commitLogPrompt( const char **log_msg, const char **tmp_file, apr_array_header_t *commit_items, void *baton, apr_pool_t *pool );
+ static void notify(void *baton, 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);
+ static void status(void *baton, const char *path, svn_wc_status_t *status);
+ static void progressCallback( apr_off_t progress, apr_off_t total, void *baton, apr_pool_t *pool);
+
+ QString chooseProtocol ( const QString& kproto ) const;
+ QString makeSvnURL ( const KURL& url ) const;
+ void initNotifier(bool is_checkout, bool is_export, bool suppress_final_line, apr_pool_t *spool);
+
+ void recordCurrentURL(const KURL& url);
+ void popupMessage( const QString& message );
+ int counter() { return m_counter; }
+ void incCounter() { m_counter++; }
+ svn_opt_revision_t createRevision( int revision, const QString& revkind, apr_pool_t *pool );
+
+ KURL myURL;
+ svn_client_ctx_t *ctx;
+ KIO::AuthInfo info;
+
+ enum SVN_METHOD {
+ SVN_CHECKOUT=1, //KURL repository, KURL workingcopy, int revnumber=-1, QString revkind(HEAD, ...) //revnumber==-1 => use of revkind
+ SVN_UPDATE=2, // KURL wc (svn:///tmp/test, int revnumber=-1, QString revkind(HEAD, ...) // revnumber==-1 => use of revkind
+ SVN_COMMIT=3,
+ SVN_LOG=4,
+ SVN_IMPORT=5,
+ SVN_ADD=6,
+ SVN_DEL=7,
+ SVN_REVERT=8,
+ SVN_STATUS=9,
+ SVN_MKDIR=10,
+ SVN_RESOLVE=11,
+ SVN_SWITCH=12,
+ SVN_DIFF=13,
+ SVN_BLAME=14,
+ SVN_INFO = 15,
+ SVN_SWITCH_RELOCATE = 16,
+ SVN_COPY = 17,
+ SVN_MERGE = 18,
+ SVN_COMMIT_2=103,
+ SVN_STATUS_2=109
+
+ };
+
+ private:
+ bool createUDSEntry( const QString& filename, const QString& user, long long int size, bool isdir, time_t mtime, KIO::UDSEntry& entry);
+ apr_pool_t *pool;
+ unsigned long int m_counter;
+};
+
+#endif
diff --git a/vcs/subversion/svn_logviewoptiondlgbase.ui b/vcs/subversion/svn_logviewoptiondlgbase.ui
new file mode 100644
index 00000000..149c82e1
--- /dev/null
+++ b/vcs/subversion/svn_logviewoptiondlgbase.ui
@@ -0,0 +1,156 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SvnLogViewOptionDlgBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>SvnLogViewOptionDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>449</width>
+ <height>288</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Subversion Log View</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="3" column="0">
+ <property name="name">
+ <cstring>pushButton1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>checkBox1</cstring>
+ </property>
+ <property name="text">
+ <string>Do not show logs before branching point</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>buttonGroup2_2</cstring>
+ </property>
+ <property name="title">
+ <string>End Revision</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>radio5</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;By Revision Number</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>radio6</cstring>
+ </property>
+ <property name="text">
+ <string>B&amp;y Revision Specifier</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>comboBox2</cstring>
+ </property>
+ </widget>
+ <widget class="KIntNumInput" row="0" column="1">
+ <property name="name">
+ <cstring>intInput2</cstring>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>pushButton2</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;ancel</string>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>buttonGroup2</cstring>
+ </property>
+ <property name="title">
+ <string>Start Revision</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>comboBox1</cstring>
+ </property>
+ </widget>
+ <widget class="KIntNumInput" row="0" column="1">
+ <property name="name">
+ <cstring>intInput1</cstring>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>radio3</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;By Revision Number</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>radio4</cstring>
+ </property>
+ <property name="text">
+ <string>B&amp;y Revision Specifier</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>pushButton1</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnLogViewOptionDlgBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>pushButton2</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnLogViewOptionDlgBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+</includehints>
+</UI>
diff --git a/vcs/subversion/svn_logviewwidget.cpp b/vcs/subversion/svn_logviewwidget.cpp
new file mode 100644
index 00000000..c6aae452
--- /dev/null
+++ b/vcs/subversion/svn_logviewwidget.cpp
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library 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.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "svn_logviewwidget.h"
+#include "svn_blamewidget.h"
+#include "subversion_core.h"
+#include "subversion_global.h"
+#include <kdevproject.h>
+#include <ktextedit.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <qradiobutton.h>
+#include <qcombobox.h>
+#include <knuminput.h>
+#include <qcheckbox.h>
+
+#include <qsplitter.h>
+#include <qheader.h>
+#include <qlistview.h>
+#include <qlayout.h>
+#include <qstringlist.h>
+
+SvnLogViewWidget::SvnLogViewWidget(subversionPart *part, QWidget *parent)
+ :QWidget(parent), m_part(part)
+{
+ m_layout = new QGridLayout( this, 1, 1, 11, 6, "SvnLogViewWidgetBaseLayout");
+
+ splitter1 = new QSplitter( this, "splitter1" );
+ splitter1->setOrientation( QSplitter::Horizontal );
+ splitter1->setMargin(1);
+
+ listView1 = new QListView( splitter1, "listView1" );
+ listView1->addColumn( i18n( "Rev" ) );
+ listView1->addColumn( i18n( "Date" ) );
+ listView1->addColumn( i18n( "Author" ) );
+ listView1->addColumn( i18n( "Comment" ) );
+ listView1->resize( QSize(1, 1).expandedTo(minimumSizeHint()) );
+ QFont listView1_font( listView1->font() );
+ listView1_font.setPointSize( 9 );
+ listView1->setFont( listView1_font );
+ listView1->setAllColumnsShowFocus( TRUE );
+ listView1->setShowSortIndicator( TRUE );
+
+ textEdit1 = new KTextEdit( splitter1, "textEdit1" );
+ textEdit1->resize( QSize(1, 1).expandedTo(minimumSizeHint()) );
+ QFont textEdit1_font( textEdit1->font() );
+ textEdit1_font.setPointSize( 9 );
+ textEdit1->setFont( textEdit1_font );
+ textEdit1->setFocusPolicy( QTextEdit::WheelFocus );
+ textEdit1->setReadOnly( TRUE );
+
+ m_layout->addWidget( splitter1, 0, 0 );
+ m_layout->setMargin(1);
+
+ resize( QSize(692, 343).expandedTo(minimumSizeHint()) );
+ clearWState( WState_Polished );
+
+ connect( listView1, SIGNAL(clicked( QListViewItem *)), this, SLOT(slotClicked(QListViewItem*)) );
+ connect( listView1, SIGNAL(contextMenuRequested( QListViewItem*, const QPoint&, int )),
+ this, SLOT(contextMenuRequested(QListViewItem*, const QPoint&, int)) );
+}
+SvnLogViewWidget::~SvnLogViewWidget()
+{
+}
+
+void SvnLogViewWidget::setLogResult( QValueList<SvnLogHolder> *loglist )
+{
+ this->listView1->clear();
+ this->textEdit1->clear();
+ this->listView1->setSorting( 1, false );
+
+ for( QValueList<SvnLogHolder>::Iterator it=loglist->begin(); it!=loglist->end(); ++it ){
+
+ SvnLogHolder holder = *it;
+ SvnLogViewItem *item = new SvnLogViewItem(this->listView1);
+
+ QString prettyDate = holder.date.left(16).replace(10, 1, ' ');
+
+ item->setText(0, holder.rev );
+ item->setText(1, prettyDate );
+ item->setText(2, holder.author );
+ item->setText(3, holder.logMsg.simplifyWhiteSpace() );
+
+ item->m_pathList = holder.pathList;
+ item->m_message = holder.logMsg;
+ }
+// this->listView1->show();
+}
+
+void SvnLogViewWidget::setRequestedUrl( QString reqUrl )
+{
+ m_reqUrl = reqUrl;
+}
+
+void SvnLogViewWidget::slotClicked( QListViewItem *oneItem )
+{
+ if( !oneItem ) return;
+ SvnLogViewItem *item = dynamic_cast<SvnLogViewItem*>( oneItem );
+ if( !item ) return;
+ textEdit1->clear();
+ textEdit1->append( item->m_pathList );
+ textEdit1->append( "\n\n" );
+ textEdit1->append( item->m_message + "\n" );
+}
+void SvnLogViewWidget::contextMenuRequested( QListViewItem *item, const QPoint & pos, int col )
+{
+ if( !item || col == -1 )
+ return;
+ m_ctxLogItem = dynamic_cast<SvnLogViewItem*>(item);
+ if( !m_ctxLogItem )
+ return;
+ QPopupMenu *menu = new QPopupMenu(this);
+ menu->insertItem( i18n("Blame this revision"), this, SLOT(blameThis()) );
+ menu->insertItem( i18n("Difference to previous revision"), this, SLOT(diffToPrevious()) );
+ menu->exec( pos );
+}
+void SvnLogViewWidget::blameThis()
+{
+ if( !m_ctxLogItem ){
+ KMessageBox::error( this, i18n("No revision was clicked"), i18n("error") );
+ return;
+ }
+ // note that blame is done on single file.
+ QStringList modifies = QStringList::split( "\n", m_ctxLogItem->m_pathList, false );
+ QString selectedPath;
+ if( modifies.count() > 1 ){
+ SvnBlameFileSelectDlg dlg(this);
+ dlg.setCandidate( &modifies );
+ if( dlg.exec() == QDialog::Accepted ){
+ selectedPath = dlg.selected();
+ } else{
+ return;
+ }
+
+ } else if( modifies.count() == 1 ){
+ selectedPath = *( modifies.at(0) );
+ } else {
+ return;
+ }
+
+ QString relPath = selectedPath.section( '/', 1 );
+
+ QValueList< SvnGlobal::SvnInfoHolder > holderList = m_part->m_prjInfoMap.values();
+ SvnGlobal::SvnInfoHolder holder;
+ if( holderList.count() > 0 ){
+ // get full Url
+ holder = holderList.first();
+ QString absPath = holder.reposRootUrl.url(-1) + '/' + relPath;
+ kdDebug(9036) << " Blame requested on path " << absPath << endl;
+ // get revision
+ int revEnd = m_ctxLogItem->text(0).toInt();
+ // final request
+ m_part->svncore()->blame( KURL(absPath), SvnGlobal::dont_touch, 0, "", revEnd, "" );
+ }
+ else{
+ return;
+ }
+}
+
+void SvnLogViewWidget::diffToPrevious()
+{
+ if( !m_ctxLogItem ){
+ KMessageBox::error( this, i18n("No revision was clicked"), i18n("error") );
+ return;
+ }
+ int revThis = m_ctxLogItem->text(0).toInt();
+ int revPrev = revThis - 1;
+ kdDebug(9036) << " Diff to prev requested on " << m_reqUrl << endl;
+ m_part->svncore()->diffAsync( m_reqUrl, m_reqUrl, revPrev, "", revThis, "",
+ true/*recurse*/, true/*peg_diff*/ );
+}
+
+SvnLogViewOptionDlg::SvnLogViewOptionDlg( QWidget *parent, const char* name, bool modal, WFlags f )
+: SvnLogViewOptionDlgBase( parent, name, modal,f )
+{
+// radio1->setChecked(true); //repository log
+ radio4->setChecked(true); //start revistion by revision keyword
+ radio5->setChecked(true); //end revision by revision number
+ reinstallRevisionSpecifiers();
+ connect( intInput1, SIGNAL(valueChanged(int)), this, SLOT(setStartRevnumRadio()) );
+ connect( comboBox1, SIGNAL(activated(const QString&)), this, SLOT(setStartRevkindRadio()) );
+ connect( intInput2, SIGNAL(valueChanged(int)), this, SLOT(setEndRevnumRadio()) );
+ connect( comboBox2, SIGNAL(activated(const QString&)), this, SLOT(setEndRevkindRadio()) );
+}
+SvnLogViewOptionDlg::~SvnLogViewOptionDlg()
+{}
+void SvnLogViewOptionDlg::reinstallRevisionSpecifiers()
+{
+ comboBox1->clear();
+ comboBox2->clear();
+
+ QStringList items;
+ items << "HEAD" << "BASE" << "PREV" << "COMMITTED";
+ comboBox1->insertStringList( items );
+ comboBox2->insertStringList( items );
+}
+int SvnLogViewOptionDlg::revstart()
+{
+ if( !radio3->isChecked() ){
+ return -1;
+ } else{
+ return intInput1->value();
+ }
+}
+QString SvnLogViewOptionDlg::revKindStart()
+{
+ if( !radio4->isChecked() ){
+ return QString("");
+ } else{
+ return comboBox1->currentText();
+ }
+}
+int SvnLogViewOptionDlg::revend()
+{
+ if( !radio5->isChecked() ){
+ return -1;
+ } else{
+ return intInput2->value();
+ }
+}
+QString SvnLogViewOptionDlg::revKindEnd()
+{
+ if( !radio6->isChecked() ){
+ return QString("");
+ } else{
+ return comboBox2->currentText();
+ }
+}
+bool SvnLogViewOptionDlg::strictNode()
+{
+ if( checkBox1->isChecked() ){
+ return true;
+ } else{
+ return false;
+ }
+}
+void SvnLogViewOptionDlg::setStartRevnumRadio()
+{
+ radio3->setChecked(true);
+}
+void SvnLogViewOptionDlg::setStartRevkindRadio()
+{
+ radio4->setChecked(true);
+}
+void SvnLogViewOptionDlg::setEndRevnumRadio()
+{
+ radio5->setChecked(true);
+}
+void SvnLogViewOptionDlg::setEndRevkindRadio()
+{
+ radio6->setChecked(true);
+}
+
+#include "svn_logviewwidget.moc"
+
diff --git a/vcs/subversion/svn_logviewwidget.h b/vcs/subversion/svn_logviewwidget.h
new file mode 100644
index 00000000..40bf7e38
--- /dev/null
+++ b/vcs/subversion/svn_logviewwidget.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library 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.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef SVNLOGVIEWWIDGET_H
+#define SVNLOGVIEWWIDGET_H
+
+#include "subversion_widget.h"
+#include "svn_logviewoptiondlgbase.h"
+// #include "subversion_part.h"
+#include <qvaluelist.h>
+#include <qlistview.h>
+class subversionPart;
+// class QWidget;
+#include <qwidget.h>
+class KTextEdit;
+class QSplitter;
+class QGridLayout;
+class SvnLogViewItem;
+
+class SvnLogHolder{
+ public:
+ SvnLogHolder(){};
+ ~SvnLogHolder(){};
+ QString author;
+ QString date;
+ QString logMsg;
+ QString pathList;
+ QString rev;
+};
+
+class SvnLogViewWidget : public /*SvnLogViewWidgetBase*/ QWidget {
+ Q_OBJECT
+public:
+ SvnLogViewWidget(subversionPart *part, QWidget *parent);
+ virtual ~SvnLogViewWidget();
+ void setLogResult( QValueList<SvnLogHolder> *loglist );
+ void setRequestedUrl( QString url );
+
+protected slots:
+ void slotClicked( QListViewItem* item );
+ void contextMenuRequested( QListViewItem *item, const QPoint & pos, int col );
+ void blameThis();
+ void diffToPrevious();
+
+private:
+ QString m_reqUrl;
+ subversionPart *m_part;
+ SvnLogViewItem* m_ctxLogItem;
+
+ QSplitter* splitter1;
+ QListView* listView1;
+ KTextEdit* textEdit1;
+ QGridLayout* m_layout;
+
+};
+
+class SvnLogViewOptionDlg : public SvnLogViewOptionDlgBase {
+ Q_OBJECT
+public:
+ SvnLogViewOptionDlg(QWidget *parent=0, const char* name=0, bool modal=TRUE, WFlags f=0);
+ ~SvnLogViewOptionDlg();
+ int revstart();
+ QString revKindStart();
+ int revend();
+ QString revKindEnd();
+ bool strictNode();
+public slots:
+ void reinstallRevisionSpecifiers();
+ void setStartRevnumRadio();
+ void setStartRevkindRadio();
+ void setEndRevnumRadio();
+ void setEndRevkindRadio();
+};
+
+#endif
+
diff --git a/vcs/subversion/svn_mergeoptiondlgbase.ui b/vcs/subversion/svn_mergeoptiondlgbase.ui
new file mode 100644
index 00000000..0ad25c83
--- /dev/null
+++ b/vcs/subversion/svn_mergeoptiondlgbase.ui
@@ -0,0 +1,374 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SvnMergeOptionDialogBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>SvnMergeOptionDialogBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>473</width>
+ <height>590</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Subversion Merge</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Destination</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Destination working path</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="1" column="0">
+ <property name="name">
+ <cstring>dest</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>buttonGroup2</cstring>
+ </property>
+ <property name="title">
+ <string>Source 1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KIntNumInput" row="3" column="1">
+ <property name="name">
+ <cstring>revnum1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minValue">
+ <number>-1</number>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="3" column="0">
+ <property name="name">
+ <cstring>revnumbtn1</cstring>
+ </property>
+ <property name="text">
+ <string>Number:</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="3" column="2">
+ <property name="name">
+ <cstring>revkindbtn1</cstring>
+ </property>
+ <property name="text">
+ <string>Keyword:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="3" column="3">
+ <item>
+ <property name="text">
+ <string>HEAD</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BASE</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>COMMITTED</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>PREV</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>revkind1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <property name="currentItem">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="1" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>src1</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Source URL or working path:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Specify revision as</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>buttonGroup2_2</cstring>
+ </property>
+ <property name="title">
+ <string>Source 2</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="3" column="0">
+ <property name="name">
+ <cstring>revnumbtn2</cstring>
+ </property>
+ <property name="text">
+ <string>Number:</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="3" column="2">
+ <property name="name">
+ <cstring>revkindbtn2</cstring>
+ </property>
+ <property name="text">
+ <string>Keyword:</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="KURLRequester" row="1" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>src2</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Specify revision as</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="3" column="3">
+ <item>
+ <property name="text">
+ <string>HEAD</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>BASE</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>COMMITTED</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>PREV</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>revkind2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <property name="currentItem">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="KIntNumInput" row="3" column="1">
+ <property name="name">
+ <cstring>revnum2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minValue">
+ <number>-1</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Source URL or working path:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QPushButton" row="7" column="1">
+ <property name="name">
+ <cstring>okBtn</cstring>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ <spacer row="7" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>171</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="7" column="2">
+ <property name="name">
+ <cstring>cancelBtn</cstring>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="4" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>forceCheck</cstring>
+ </property>
+ <property name="text">
+ <string>--force (Force to delete locally modified or unversioned items.)</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>nonRecurse</cstring>
+ </property>
+ <property name="text">
+ <string>--non-recursive</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="5" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>ignoreAncestryCheck</cstring>
+ </property>
+ <property name="text">
+ <string>--ignore-ancestry</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="6" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>dryRunCheck</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>--dry-run (Only receive full result notification
+ without actually modifying working copy)</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>okBtn</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnMergeOptionDialogBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>cancelBtn</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnMergeOptionDialogBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+</includehints>
+</UI>
diff --git a/vcs/subversion/svn_mergewidget.cpp b/vcs/subversion/svn_mergewidget.cpp
new file mode 100644
index 00000000..6a8fc0b3
--- /dev/null
+++ b/vcs/subversion/svn_mergewidget.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library 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.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "svn_mergewidget.h"
+#include "subversion_global.h"
+#include <kurlrequester.h>
+#include <qradiobutton.h>
+#include <knuminput.h>
+#include <qcheckbox.h>
+#include <kcombobox.h>
+
+using namespace SvnGlobal;
+
+SvnMergeDialog::SvnMergeDialog( const KURL &wcTarget, QWidget *parent )
+ : SvnMergeOptionDialogBase( parent )
+{
+ dest->setURL( wcTarget.prettyURL() );
+
+ connect( revnumbtn1, SIGNAL(toggled(bool)), revnum1, SLOT(setEnabled(bool)) );
+ connect( revnumbtn1, SIGNAL(toggled(bool)), revkind1, SLOT(setDisabled(bool)) );
+ connect( revnumbtn2, SIGNAL(toggled(bool)), revnum2, SLOT(setEnabled(bool)) );
+ connect( revnumbtn2, SIGNAL(toggled(bool)), revkind2, SLOT(setDisabled(bool)) );
+ revkind1->setDisabled(true);
+ revnum2->setDisabled(true);
+}
+
+SvnMergeDialog::~SvnMergeDialog()
+{
+}
+
+KURL SvnMergeDialog::source1()
+{
+ return KURL( src1->url() );
+}
+SvnRevision SvnMergeDialog::rev1()
+{
+ SvnRevision rev;
+
+ if( revkindbtn1->isChecked() ){
+ rev.revNum = -1;
+ rev.revKind = revkind1->currentText();
+ } else {
+ rev.revNum = revnum1->value();
+ rev.revKind = "UNSPECIFIED";
+ }
+ return rev;
+}
+KURL SvnMergeDialog::source2()
+{
+ return KURL( src2->url() );
+}
+SvnRevision SvnMergeDialog::rev2()
+{
+ SvnRevision rev;
+
+ if( revkindbtn2->isChecked() ){
+ rev.revNum = -1;
+ rev.revKind = revkind2->currentText();
+ } else {
+ rev.revNum = revnum2->value();
+ rev.revKind = "UNSPECIFIED";
+ }
+ return rev;
+}
+bool SvnMergeDialog::recurse()
+{
+ return !(nonRecurse->isChecked());
+}
+bool SvnMergeDialog::force()
+{
+ return forceCheck->isChecked();
+}
+bool SvnMergeDialog::ignoreAncestry()
+{
+ return ignoreAncestryCheck->isChecked();
+}
+bool SvnMergeDialog::dryRun()
+{
+ return dryRunCheck->isChecked();
+}
+
+#include "svn_mergewidget.moc"
diff --git a/vcs/subversion/svn_mergewidget.h b/vcs/subversion/svn_mergewidget.h
new file mode 100644
index 00000000..ff54a6da
--- /dev/null
+++ b/vcs/subversion/svn_mergewidget.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 Dukju Ahn (dukjuahn@gmail.com)
+ *
+ * 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
+ * Library 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.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef SVN_MERGEWIDGET_H
+#define SVN_MERGEWIDGET_H
+
+#include "svn_mergeoptiondlgbase.h"
+namespace SvnGlobal
+{
+ class SvnRevision;
+}
+
+class KURL;
+
+class SvnMergeDialog : public SvnMergeOptionDialogBase
+{
+ Q_OBJECT
+public:
+ SvnMergeDialog( const KURL &wcTarget, QWidget *parent = NULL );
+ virtual ~SvnMergeDialog();
+
+ KURL source1();
+ SvnGlobal::SvnRevision rev1();
+ KURL source2();
+ SvnGlobal::SvnRevision rev2();
+ bool recurse();
+ bool force();
+ bool ignoreAncestry();
+ bool dryRun();
+
+};
+
+#endif
diff --git a/vcs/subversion/svn_switchdlgbase.ui b/vcs/subversion/svn_switchdlgbase.ui
new file mode 100644
index 00000000..02257196
--- /dev/null
+++ b/vcs/subversion/svn_switchdlgbase.ui
@@ -0,0 +1,213 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SvnSwitchDlgBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>SvnSwitchDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>603</width>
+ <height>255</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Subversion Switch</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="4" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>nonRecurseCheck</cstring>
+ </property>
+ <property name="text">
+ <string>Non-recursive. (Switch its immediate children only)</string>
+ </property>
+ </widget>
+ <widget class="Line" row="5" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="6" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KPushButton" row="0" column="2">
+ <property name="name">
+ <cstring>cancelBtn</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ <spacer row="0" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>150</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton" row="0" column="1">
+ <property name="name">
+ <cstring>okBtn</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Current Repository URL</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="2" column="1">
+ <property name="name">
+ <cstring>currentUrlEdit</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Working copy to switch</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>wcUrlEdit</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Working Mode</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>switchOnlyRadio</cstring>
+ </property>
+ <property name="text">
+ <string>svn switch</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>relocationRadio</cstring>
+ </property>
+ <property name="text">
+ <string>svn switch --relocation</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>New destination URL</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="3" column="1">
+ <property name="name">
+ <cstring>destUrlEdit</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>okBtn</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnSwitchDlgBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>cancelBtn</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnSwitchDlgBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>destUrlEdit</sender>
+ <signal>returnPressed()</signal>
+ <receiver>SvnSwitchDlgBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">svn_switchdlgbase.ui.h</include>
+</includes>
+<slots>
+ <slot>Form1_destroyed( QObject * )</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/vcs/subversion/svn_switchwidget.cpp b/vcs/subversion/svn_switchwidget.cpp
new file mode 100644
index 00000000..ec1b603c
--- /dev/null
+++ b/vcs/subversion/svn_switchwidget.cpp
@@ -0,0 +1,60 @@
+#include <kurl.h>
+#include <klineedit.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+
+#include "svn_switchwidget.h"
+#include "subversion_global.h"
+
+SvnSwitchDlg::SvnSwitchDlg( const SvnGlobal::SvnInfoHolder *holder,
+ const QString &wcPath, QWidget *parent )
+ : SvnSwitchDlgBase( parent )
+ , m_info( holder )
+{
+ connect( switchOnlyRadio, SIGNAL(clicked()), this, SLOT(resetCurrentRepositoryUrlEdit()) );
+ connect( relocationRadio , SIGNAL(clicked()), this, SLOT(resetCurrentRepositoryUrlEdit()) );
+ // set switch only
+ switchOnlyRadio->setChecked( true );
+ wcUrlEdit->setText( wcPath );
+ currentUrlEdit->setText( m_info->url.prettyURL() );
+}
+
+SvnSwitchDlg::~SvnSwitchDlg()
+{}
+
+const QString SvnSwitchDlg::currentUrl()
+{
+ return currentUrlEdit->text();
+}
+const QString SvnSwitchDlg::destUrl()
+{
+ return destUrlEdit->text();
+}
+
+bool SvnSwitchDlg::recursive()
+{
+ return (! nonRecurseCheck->isChecked() );
+}
+bool SvnSwitchDlg::switchOnly()
+{
+ return switchOnlyRadio->isChecked();
+}
+bool SvnSwitchDlg::relocation()
+{
+ return relocationRadio->isChecked();
+}
+
+void SvnSwitchDlg::resetCurrentRepositoryUrlEdit()
+{
+ if( relocation() ){
+ // only ROOT repository url should be given
+ currentUrlEdit->setText( m_info->reposRootUrl.prettyURL() );
+ } else if( switchOnly() ){
+ // the full URL of item should be given
+ currentUrlEdit->setText( m_info->url.prettyURL() );
+ } else{
+ // should not reach here!!
+ }
+}
+
+#include "svn_switchwidget.moc"
diff --git a/vcs/subversion/svn_switchwidget.h b/vcs/subversion/svn_switchwidget.h
new file mode 100644
index 00000000..643fb4b9
--- /dev/null
+++ b/vcs/subversion/svn_switchwidget.h
@@ -0,0 +1,31 @@
+#ifndef SVN_SWITCHWIDGET_H
+#define SVN_SWITCHWIDGET_H
+
+#include "svn_switchdlgbase.h"
+
+namespace SvnGlobal
+{
+ class SvnInfoHolder;
+}
+
+class SvnSwitchDlg : public SvnSwitchDlgBase
+{
+ Q_OBJECT
+public:
+ SvnSwitchDlg( const SvnGlobal::SvnInfoHolder *holder,
+ const QString &wcPath, QWidget *parent = NULL );
+ virtual ~SvnSwitchDlg();
+
+ const QString currentUrl();
+ const QString destUrl();
+ bool recursive();
+ bool switchOnly();
+ bool relocation();
+private slots:
+ void resetCurrentRepositoryUrlEdit();
+
+private:
+ const SvnGlobal::SvnInfoHolder *m_info;
+};
+
+#endif
diff --git a/vcs/subversion/svnssltrustpromptbase.ui b/vcs/subversion/svnssltrustpromptbase.ui
new file mode 100644
index 00000000..a94e345c
--- /dev/null
+++ b/vcs/subversion/svnssltrustpromptbase.ui
@@ -0,0 +1,116 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SvnSSLTrustPromptBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>SvnSSLTrustPromptBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>504</width>
+ <height>281</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>SSL Certificate Trust</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="2" column="0">
+ <property name="name">
+ <cstring>btnPermanent</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QListView" row="1" column="0" rowspan="1" colspan="3">
+ <column>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>listView1</cstring>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="2">
+ <property name="name">
+ <cstring>btnReject</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>btnTemporary</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>errMsgLabel</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>btnPermanent</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnSSLTrustPromptBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>btnTemporary</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnSSLTrustPromptBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>btnReject</sender>
+ <signal>clicked()</signal>
+ <receiver>SvnSSLTrustPromptBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>