summaryrefslogtreecommitdiffstats
path: root/src/svnqt
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-15 17:32:48 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-15 17:32:48 +0000
commite2f541c98dfa4081fa3ab3d28f08ea2309281884 (patch)
treecb721a55bc88753ddeb9754dc98ef45e2850ce30 /src/svnqt
downloadtdesvn-e2f541c98dfa4081fa3ab3d28f08ea2309281884.tar.gz
tdesvn-e2f541c98dfa4081fa3ab3d28f08ea2309281884.zip
Added KDE3 version of kdesvn
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kdesvn@1103685 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/svnqt')
-rw-r--r--src/svnqt/CMakeLists.txt205
-rw-r--r--src/svnqt/annotate_line.hpp159
-rw-r--r--src/svnqt/apr.cpp52
-rw-r--r--src/svnqt/apr.hpp69
-rw-r--r--src/svnqt/cache/DatabaseException.cpp12
-rw-r--r--src/svnqt/cache/DatabaseException.hpp35
-rw-r--r--src/svnqt/cache/LogCache.cpp468
-rw-r--r--src/svnqt/cache/LogCache.hpp41
-rw-r--r--src/svnqt/cache/ReposLog.cpp535
-rw-r--r--src/svnqt/cache/ReposLog.hpp70
-rw-r--r--src/svnqt/cache/sqlite3/README32
-rw-r--r--src/svnqt/cache/sqlite3/qsql_sqlite3.cpp485
-rw-r--r--src/svnqt/cache/sqlite3/qsql_sqlite3.h90
-rw-r--r--src/svnqt/cache/sqlite3/qsqlcachedresult.cpp260
-rw-r--r--src/svnqt/cache/sqlite3/qsqlcachedresult.h81
-rw-r--r--src/svnqt/cache/test/CMakeLists.txt19
-rw-r--r--src/svnqt/cache/test/sqlite.cpp111
-rw-r--r--src/svnqt/cache/test/testconfig.h.in8
-rw-r--r--src/svnqt/check.hpp50
-rw-r--r--src/svnqt/client.cpp104
-rw-r--r--src/svnqt/client.hpp882
-rw-r--r--src/svnqt/client_annotate.cpp142
-rw-r--r--src/svnqt/client_cat.cpp105
-rw-r--r--src/svnqt/client_diff.cpp184
-rw-r--r--src/svnqt/client_impl.cpp123
-rw-r--r--src/svnqt/client_impl.hpp881
-rw-r--r--src/svnqt/client_lock.cpp63
-rw-r--r--src/svnqt/client_ls.cpp237
-rw-r--r--src/svnqt/client_merge.cpp180
-rw-r--r--src/svnqt/client_modify.cpp722
-rw-r--r--src/svnqt/client_property.cpp450
-rw-r--r--src/svnqt/client_status.cpp736
-rw-r--r--src/svnqt/cmakemodules/FindSqlite.cmake32
-rw-r--r--src/svnqt/cmakemodules/FindSubversion.cmake352
-rw-r--r--src/svnqt/commititem.cpp167
-rw-r--r--src/svnqt/commititem.hpp101
-rw-r--r--src/svnqt/conflictdescription.cpp185
-rw-r--r--src/svnqt/conflictdescription.hpp96
-rw-r--r--src/svnqt/conflictresult.cpp131
-rw-r--r--src/svnqt/conflictresult.hpp78
-rw-r--r--src/svnqt/context.cpp136
-rw-r--r--src/svnqt/context.hpp176
-rw-r--r--src/svnqt/context_listener.hpp271
-rw-r--r--src/svnqt/contextdata.cpp782
-rw-r--r--src/svnqt/contextdata.hpp338
-rw-r--r--src/svnqt/datetime.cpp170
-rw-r--r--src/svnqt/datetime.hpp166
-rw-r--r--src/svnqt/diff_data.cpp145
-rw-r--r--src/svnqt/diff_data.hpp75
-rw-r--r--src/svnqt/diffoptions.cpp144
-rw-r--r--src/svnqt/diffoptions.hpp79
-rw-r--r--src/svnqt/dirent.cpp186
-rw-r--r--src/svnqt/dirent.hpp131
-rw-r--r--src/svnqt/entry.cpp394
-rw-r--r--src/svnqt/entry.hpp245
-rw-r--r--src/svnqt/exception.cpp224
-rw-r--r--src/svnqt/exception.hpp138
-rw-r--r--src/svnqt/helper.hpp98
-rw-r--r--src/svnqt/info_entry.cpp311
-rw-r--r--src/svnqt/info_entry.hpp118
-rw-r--r--src/svnqt/lock_entry.cpp141
-rw-r--r--src/svnqt/lock_entry.hpp90
-rw-r--r--src/svnqt/log_entry.cpp190
-rw-r--r--src/svnqt/log_entry.hpp137
-rw-r--r--src/svnqt/path.cpp290
-rw-r--r--src/svnqt/path.hpp200
-rw-r--r--src/svnqt/pool.cpp94
-rw-r--r--src/svnqt/pool.hpp92
-rw-r--r--src/svnqt/repository.cpp104
-rw-r--r--src/svnqt/repository.hpp119
-rw-r--r--src/svnqt/repositorydata.cpp250
-rw-r--r--src/svnqt/repositorydata.hpp73
-rw-r--r--src/svnqt/repositorylistener.cpp37
-rw-r--r--src/svnqt/repositorylistener.hpp56
-rw-r--r--src/svnqt/revision.cpp299
-rw-r--r--src/svnqt/revision.hpp222
-rw-r--r--src/svnqt/shared_pointer.hpp193
-rw-r--r--src/svnqt/smart_pointer.hpp146
-rw-r--r--src/svnqt/status.cpp319
-rw-r--r--src/svnqt/status.hpp187
-rw-r--r--src/svnqt/stringarray.cpp121
-rw-r--r--src/svnqt/stringarray.hpp73
-rw-r--r--src/svnqt/svnfilestream.cpp134
-rw-r--r--src/svnqt/svnfilestream.hpp69
-rw-r--r--src/svnqt/svnqt_defines.hpp.in43
-rw-r--r--src/svnqt/svnqttypes.hpp104
-rw-r--r--src/svnqt/svnstream.cpp263
-rw-r--r--src/svnqt/svnstream.hpp164
-rw-r--r--src/svnqt/targets.cpp170
-rw-r--r--src/svnqt/targets.hpp168
-rw-r--r--src/svnqt/testmain.cpp62
-rw-r--r--src/svnqt/tests/CMakeLists.txt23
-rw-r--r--src/svnqt/tests/ckpath.cpp24
-rw-r--r--src/svnqt/tests/crepo.cpp63
-rw-r--r--src/svnqt/tests/lsdir.cpp78
-rw-r--r--src/svnqt/tests/testconfig.h.in7
-rw-r--r--src/svnqt/tests/testlistener.h37
-rw-r--r--src/svnqt/url.cpp209
-rw-r--r--src/svnqt/url.hpp104
-rw-r--r--src/svnqt/version_check.cpp70
-rw-r--r--src/svnqt/version_check.hpp43
-rw-r--r--src/svnqt/wc.cpp129
-rw-r--r--src/svnqt/wc.hpp96
103 files changed, 18553 insertions, 0 deletions
diff --git a/src/svnqt/CMakeLists.txt b/src/svnqt/CMakeLists.txt
new file mode 100644
index 0000000..bf50a6f
--- /dev/null
+++ b/src/svnqt/CMakeLists.txt
@@ -0,0 +1,205 @@
+SET(SOURCES
+ apr.cpp
+ client_annotate.cpp
+ client_cat.cpp
+ client.cpp
+ client_diff.cpp
+ client_ls.cpp
+ client_modify.cpp
+ client_property.cpp
+ client_status.cpp
+ context.cpp
+ datetime.cpp
+ dirent.cpp
+ entry.cpp
+ exception.cpp
+ log_entry.cpp
+ path.cpp
+ pool.cpp
+ revision.cpp
+ status.cpp
+ targets.cpp
+ url.cpp
+ version_check.cpp
+ wc.cpp
+ lock_entry.cpp
+ client_lock.cpp
+ info_entry.cpp
+ client_impl.cpp
+ contextdata.cpp
+ commititem.cpp
+ repository.cpp
+ repositorydata.cpp
+ repositorylistener.cpp
+ svnstream.cpp
+ diff_data.cpp
+ svnfilestream.cpp
+ stringarray.cpp
+ diffoptions.cpp
+ conflictdescription.cpp
+ conflictresult.cpp
+ client_merge.cpp
+ cache/LogCache.cpp
+ cache/ReposLog.cpp
+ cache/DatabaseException.hpp
+ cache/DatabaseException.cpp
+ )
+
+IF (NOT QT4_FOUND)
+ IF (SQLITE_FOUND)
+ MESSAGE(STATUS "Build own sqlite3 database modul")
+ SET(SOURCES
+ ${SOURCES}
+ cache/sqlite3/qsqlcachedresult.cpp
+ cache/sqlite3/qsql_sqlite3.cpp
+ cache/sqlite3/qsqlcachedresult.h
+ cache/sqlite3/qsql_sqlite3.h
+ )
+ ELSE (SQLITE_FOUND)
+ MESSAGE(SEND_ERROR "The QT3 version requires sqlite3 but could not found")
+ ENDIF (SQLITE_FOUND)
+ELSE (NOT QT4_FOUND)
+ MESSAGE(STATUS "Build with QT4.")
+ ADD_DEFINITIONS(-DNO_SQLITE3)
+ENDIF (NOT QT4_FOUND)
+
+SET(CACHEINST_HEADERS
+ cache/LogCache.hpp
+ cache/ReposLog.hpp
+ cache/DatabaseException.hpp
+)
+
+SET(INST_HEADERS
+ annotate_line.hpp
+ apr.hpp
+ check.hpp
+ client.hpp
+ commititem.hpp
+ context.hpp
+ context_listener.hpp
+ datetime.hpp
+ dirent.hpp
+ entry.hpp
+ exception.hpp
+ info_entry.hpp
+ lock_entry.hpp
+ log_entry.hpp
+ path.hpp
+ pool.hpp
+ repository.hpp
+ repositorylistener.hpp
+ revision.hpp
+ smart_pointer.hpp
+ shared_pointer.hpp
+ status.hpp
+ svnfilestream.hpp
+ svnstream.hpp
+ svnqttypes.hpp
+ targets.hpp
+ url.hpp
+ version_check.hpp
+ wc.hpp
+ stringarray.hpp
+ diffoptions.hpp
+ conflictdescription.hpp
+ conflictresult.hpp
+ )
+
+FILE(GLOB svnhdr RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.hpp")
+SET(svnhdr ${svnhdr} ${CACHE_INST_HEADERS})
+
+IF(QT4_FOUND)
+ MESSAGE(STATUS "Qt: ${QT_LIBRARY_DIR}")
+ MESSAGE(STATUS "Qt: ${QT_QTCORE_LIBRARY}")
+ SET(TOUTF8 "toUtf8")
+ SET(FROMUTF8 "fromUtf8")
+ SET(QLIST "QList")
+ SET(TOASCII "toAscii")
+ SET(HOMEDIR "homePath")
+ SET(svnqt-name svnqt-qt4)
+ SET(QDATABASE "QSqlDatabase")
+ SET(QLONG "qlonglong")
+ELSE(QT4_FOUND)
+ IF(QT_FOUND)
+ SET(TOUTF8 "utf8")
+ SET(FROMUTF8 "fromUtf8")
+ SET(QLIST "QValueList")
+ SET(TOASCII "latin1")
+ SET(HOMEDIR "homeDirPath")
+ SET(QDATABASE "QSqlDatabase*")
+ SET(QLONG "Q_LLONG")
+ ENDIF(QT_FOUND)
+ SET(svnqt-name svnqt)
+ENDIF(QT4_FOUND)
+
+IF (HAVE_GCC_VISIBILITY)
+ SET(_SVNQT_EXPORT "__attribute__ ((visibility(\"default\")))")
+ SET(_SVNQT_NOEXPORT "__attribute__ ((visibility(\"hidden\")))")
+ENDIF (HAVE_GCC_VISIBILITY)
+IF (WIN32)
+ SET(_SVNQT_EXPORT "__declspec(dllexport)")
+ENDIF (WIN32)
+
+CONFIGURE_FILE(
+ "${CMAKE_CURRENT_SOURCE_DIR}/svnqt_defines.hpp.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/svnqt_defines.hpp"
+ IMMEDIATE
+ @ONLY)
+
+SET(INST_HEADERS ${INST_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/svnqt_defines.hpp)
+INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
+
+ADD_LIBRARY(${svnqt-name} SHARED ${SOURCES} ${svnhdr})
+IF(WIN32)
+ ADD_DEFINITIONS(-D_USE_32BIT_TIME_T)
+ELSE(WIN32)
+ SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX})
+ SET_TARGET_PROPERTIES(${svnqt-name}
+ PROPERTIES
+ COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS})
+ENDIF(WIN32)
+
+SET(LIB_MAJOR 4)
+SET(LIB_MINOR 2)
+SET(LIB_RELEASE 2)
+
+SET(_soversion ${LIB_MAJOR}.${LIB_MINOR}.${LIB_RELEASE})
+
+SET_TARGET_PROPERTIES(${svnqt-name} PROPERTIES
+ SOVERSION ${LIB_MAJOR}
+ VERSION ${_soversion})
+
+SET(ALL_LINKFLAGS ${APR_EXTRA_LIBFLAGS})
+SET(ALL_LINKFLAGS "${ALL_LINKFLAGS} ${APU_EXTRA_LIBFLAGS}")
+SET_TARGET_PROPERTIES(${svnqt-name} PROPERTIES LINK_FLAGS "${ALL_LINKFLAGS} ${LINK_NO_UNDEFINED}")
+TARGET_LINK_LIBRARIES(${svnqt-name} ${QT_LIBRARIES} ${SUBVERSION_ALL_LIBS})
+
+IF (SQLITE_FOUND AND NOT QT4_FOUND)
+ TARGET_LINK_LIBRARIES(${svnqt-name} ${SQLITE_LIBRARIES})
+ INCLUDE_DIRECTORIES(SQLITE_INCLUDE_DIR)
+ELSE (SQLITE_FOUND AND NOT QT4_FOUND)
+ TARGET_LINK_LIBRARIES(${svnqt-name} ${QT_QTSQL_LIBRARY})
+ENDIF (SQLITE_FOUND AND NOT QT4_FOUND)
+
+IF (WIN32)
+ TARGET_LINK_LIBRARIES( ${svnqt-name} wsock32.lib )
+ENDIF (WIN32)
+
+# Just a small linking test
+IF (BUILD_TESTS)
+ ADD_EXECUTABLE(testlink testmain.cpp)
+ TARGET_LINK_LIBRARIES(testlink ${svnqt-name})
+ENDIF (BUILD_TESTS)
+
+# install rules
+# in win32 we don't install it
+IF(NOT WIN32)
+ INSTALL(TARGETS ${svnqt-name} DESTINATION ${LIB_INSTALL_DIR})
+ INSTALL(FILES ${INST_HEADERS} DESTINATION include/${svnqt-name})
+ INSTALL(FILES ${CACHEINST_HEADERS} DESTINATION include/${svnqt-name}/cache)
+ENDIF(NOT WIN32)
+
+IF (BUILD_TESTS)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(cache/test)
+ENDIF (BUILD_TESTS)
diff --git a/src/svnqt/annotate_line.hpp b/src/svnqt/annotate_line.hpp
new file mode 100644
index 0000000..c8a0a6f
--- /dev/null
+++ b/src/svnqt/annotate_line.hpp
@@ -0,0 +1,159 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#ifndef _SVNCPP_ANNOTATE_LINE_HPP_
+#define _SVNCPP_ANNOTATE_LINE_HPP_
+
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qstring.h>
+#include <qdatetime.h>
+
+namespace svn
+{
+ /**
+ * This class holds the data for one line in an annotation
+ */
+ class AnnotateLine
+ {
+ public:
+ AnnotateLine (QLONG line_no,
+ QLONG revision,
+ const char *author,
+ const char *date,
+ const char *line)
+ : m_line_no (line_no), m_revision (revision),
+ m_date( (date&&strlen(date))?QDateTime::fromString(QString::FROMUTF8(date),Qt::ISODate):QDateTime()),
+ m_line(line?line:""),m_author(author?author:""),
+ m_merge_revision(-1),
+ m_merge_date(QDateTime()),
+ m_merge_author(""),m_merge_path("")
+
+ {
+ }
+
+ AnnotateLine (QLONG line_no,
+ QLONG revision,
+ const char *author,
+ const char *date,
+ const char *line,
+ QLONG merge_revision,
+ const char *merge_author,
+ const char *merge_date,
+ const char *merge_path
+ )
+ : m_line_no (line_no), m_revision (revision),
+ m_date( (date&&strlen(date))?QDateTime::fromString(QString::FROMUTF8(date),Qt::ISODate):QDateTime()),
+ m_line(line?line:""),m_author(author?author:""),
+ m_merge_revision(merge_revision),
+ m_merge_date( (merge_date&&strlen(merge_date))?QDateTime::fromString(QString::FROMUTF8(merge_date),Qt::ISODate):QDateTime()),
+ m_merge_author(merge_author?merge_author:""),m_merge_path(merge_path?merge_path:"")
+ {
+ }
+
+ AnnotateLine ( const AnnotateLine &other)
+ : m_line_no (other.m_line_no), m_revision (other.m_revision), m_date (other.m_date),
+ m_line (other.m_line), m_author (other.m_author)
+ {
+ }
+ AnnotateLine()
+ : m_line_no(0),m_revision(-1),m_date(),
+ m_line(), m_author()
+ {
+ }
+
+ /**
+ * destructor
+ */
+ virtual ~AnnotateLine ()
+ {
+ }
+
+ QLONG
+ lineNumber () const
+ {
+ return m_line_no;
+ }
+ QLONG
+ revision () const
+ {
+ return m_revision;
+ }
+
+
+ const QByteArray &
+ author () const
+ {
+ return m_author;
+ }
+
+
+ const QDateTime &
+ date () const
+ {
+ return m_date;
+ }
+
+
+ const QByteArray &
+ line () const
+ {
+ return m_line;
+ }
+
+ protected:
+ QLONG m_line_no;
+ QLONG m_revision;
+ QDateTime m_date;
+#if QT_VERSION < 0x040000
+ QCString m_line;
+ QCString m_author;
+#else
+ QByteArray m_line;
+ QByteArray m_author;
+#endif
+
+ QLONG m_merge_revision;
+ QDateTime m_merge_date;
+#if QT_VERSION < 0x040000
+ QCString m_merge_author;
+ QCString m_merge_path;
+#else
+ QByteArray m_merge_author;
+ QByteArray m_merge_path;
+#endif
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/apr.cpp b/src/svnqt/apr.cpp
new file mode 100644
index 0000000..ca531a0
--- /dev/null
+++ b/src/svnqt/apr.cpp
@@ -0,0 +1,52 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// apr
+#include "apr_general.h"
+
+// svncpp
+#include "apr.hpp"
+
+
+/**
+ * SvnCpp namespace.
+ */
+namespace svn
+{
+ Apr::Apr ()
+ {
+ apr_initialize ();
+ }
+
+ Apr::~Apr ()
+ {
+ apr_terminate ();
+ }
+}
diff --git a/src/svnqt/apr.hpp b/src/svnqt/apr.hpp
new file mode 100644
index 0000000..bb6655a
--- /dev/null
+++ b/src/svnqt/apr.hpp
@@ -0,0 +1,69 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_APR_H_
+#define _SVNCPP_APR_H_
+
+namespace svn
+{
+
+ /**
+ * APR class. Include this class in your application for apr
+ * support.
+ */
+ class Apr
+ {
+ public:
+ /**
+ * Default constructor. Initializes APR
+ */
+ Apr ();
+
+ /**
+ * Destructor. Terminates APR
+ */
+ ~Apr ();
+
+ private:
+ /** Disallow copy constructor */
+ Apr (const Apr &);
+
+ /** Disallow assignment operator */
+ Apr &
+ operator = (const Apr &);
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/cache/DatabaseException.cpp b/src/svnqt/cache/DatabaseException.cpp
new file mode 100644
index 0000000..85812ab
--- /dev/null
+++ b/src/svnqt/cache/DatabaseException.cpp
@@ -0,0 +1,12 @@
+#include "DatabaseException.hpp"
+
+/*!
+ \fn svn::cache::DatabaseException::DatabaseException(const QString&msg,int aNumber)throw()
+ */
+svn::cache::DatabaseException::DatabaseException(const QString&msg,int aNumber)throw()
+ : Exception(msg),m_number(aNumber)
+{
+ if (aNumber>-1) {
+ setMessage(QString("(Code %1) %2").arg(aNumber).arg(msg));
+ }
+}
diff --git a/src/svnqt/cache/DatabaseException.hpp b/src/svnqt/cache/DatabaseException.hpp
new file mode 100644
index 0000000..85e5ce4
--- /dev/null
+++ b/src/svnqt/cache/DatabaseException.hpp
@@ -0,0 +1,35 @@
+#ifndef _DATABASE_EXCEPTION_HPP
+#define _DATABASE_EXCEPTION_HPP
+
+#include "svnqt/exception.hpp"
+
+namespace svn
+{
+namespace cache
+{
+
+class SVNQT_EXPORT DatabaseException:public svn::Exception
+{
+ private:
+ DatabaseException()throw();
+ int m_number;
+
+ public:
+ DatabaseException(const QString&msg)throw()
+ : Exception(msg),m_number(-1)
+ {}
+
+ DatabaseException(const DatabaseException&src)throw()
+ : Exception(src.msg()),m_number(src.number())
+ {}
+ DatabaseException(const QString&msg,int aNumber)throw();
+ virtual ~DatabaseException()throw(){}
+ int number() const
+ {
+ return m_number;
+ }
+};
+
+}
+}
+#endif
diff --git a/src/svnqt/cache/LogCache.cpp b/src/svnqt/cache/LogCache.cpp
new file mode 100644
index 0000000..6356c6f
--- /dev/null
+++ b/src/svnqt/cache/LogCache.cpp
@@ -0,0 +1,468 @@
+#include "LogCache.hpp"
+
+#include <qdir.h>
+#include <qsql.h>
+#include <qsqldatabase.h>
+#if QT_VERSION < 0x040000
+#include <qthreadstorage.h>
+#else
+#include <QMutex>
+#include <QThreadStorage>
+#include <QSqlError>
+#include <QSqlQuery>
+#include <QVariant>
+#endif
+#include <qmap.h>
+
+#include "svnqt/path.hpp"
+#include "svnqt/cache/DatabaseException.hpp"
+
+#ifndef NO_SQLITE3
+#include "sqlite3/qsql_sqlite3.h"
+#define SQLTYPE "QSQLITE3"
+#else
+#define SQLTYPE "QSQLITE"
+#endif
+
+#define SQLMAIN "logmain-logcache"
+#define SQLMAINTABLE "logdb"
+
+namespace svn {
+namespace cache {
+
+LogCache* LogCache::mSelf = 0;
+
+class ThreadDBStore
+{
+public:
+ ThreadDBStore(){
+#if QT_VERSION < 0x040000
+ m_DB=0;
+#else
+ m_DB=QSqlDatabase();
+#endif
+ }
+ ~ThreadDBStore(){
+#if QT_VERSION < 0x040000
+ m_DB=0;
+#else
+ m_DB=QSqlDatabase();
+#endif
+ QSqlDatabase::removeDatabase(key);
+ QMap<QString,QString>::Iterator it;
+ for (it=reposCacheNames.begin();it!=reposCacheNames.end();++it) {
+#if QT_VERSION < 0x040000
+ QSqlDatabase::removeDatabase(it.data());
+#else
+ QSqlDatabase::removeDatabase(it.value());
+#endif
+ }
+ }
+
+ QDataBase m_DB;
+ QString key;
+ QMap<QString,QString> reposCacheNames;
+};
+
+class LogCacheData
+{
+
+protected:
+ QMutex m_singleDbMutex;
+
+public:
+ LogCacheData(){}
+ ~LogCacheData(){
+ if (m_mainDB.hasLocalData()) {
+ m_mainDB.setLocalData(0L);
+ }
+ }
+
+ bool checkReposDb(QDataBase aDb)
+ {
+#if QT_VERSION < 0x040000
+ if (!aDb) {
+ return false;
+ }
+ if (!aDb->open()) {
+ return false;
+ }
+#else
+ if (!aDb.open()) {
+ return false;
+ }
+#endif
+
+ QSqlQuery _q(QString::null, aDb);
+#if QT_VERSION < 0x040000
+ QStringList list = aDb->tables();
+#else
+ QStringList list = aDb.tables();
+#endif
+
+#if QT_VERSION < 0x040000
+ if (list.find("logentries")==list.end()) {
+ aDb->transaction();
+#else
+ if (list.indexOf("logentries")==-1) {
+ aDb.transaction();
+#endif
+ _q.exec("CREATE TABLE \"logentries\" (\"revision\" INTEGER UNIQUE,\"date\" INTEGER,\"author\" TEXT, \"message\" TEXT)");
+#if QT_VERSION < 0x040000
+ aDb->commit();
+#else
+ aDb.commit();
+#endif
+ }
+#if QT_VERSION < 0x040000
+ if (list.find("changeditems")==list.end()) {
+ aDb->transaction();
+#else
+ if (list.indexOf("changeditems")==-1) {
+ aDb.transaction();
+#endif
+ _q.exec("CREATE TABLE \"changeditems\" (\"revision\" INTEGER,\"changeditem\" TEXT,\"action\" TEXT,\"copyfrom\" TEXT,\"copyfromrev\" INTEGER, PRIMARY KEY(revision,changeditem,action))");
+#if QT_VERSION < 0x040000
+ aDb->commit();
+#else
+ aDb.commit();
+#endif
+ }
+#if QT_VERSION < 0x040000
+ list = aDb->tables();
+ if (list.find("logentries")==list.end() || list.find("changeditems")==list.end()) {
+#else
+ list = aDb.tables();
+ if (list.indexOf("logentries")==-1 || list.indexOf("changeditems")==-1) {
+#endif
+ return false;
+ }
+ return true;
+ }
+
+ QString createReposDB(const svn::Path&reposroot) {
+ QMutexLocker locker( &m_singleDbMutex );
+
+ QDataBase _mdb = getMainDB();
+
+ QSqlQuery query1(QString::null,_mdb);
+ QString q("insert into "+QString(SQLMAINTABLE)+" (reposroot) VALUES('"+reposroot+"')");
+#if QT_VERSION < 0x040000
+ _mdb->transaction();
+#else
+ _mdb.transaction();
+#endif
+
+ query1.exec(q);
+#if QT_VERSION < 0x040000
+ _mdb->commit();
+#else
+ _mdb.commit();
+#endif
+ QSqlQuery query(QString::null,_mdb);
+ query.prepare(s_reposSelect);
+ query.bindValue(0,reposroot.native());
+ query.exec();
+ QString db;
+#if QT_VERSION < 0x040000
+ if (query.lastError().type()==QSqlError::None && query.next()) {
+#else
+ if (query.lastError().type()==QSqlError::NoError && query.next()) {
+#endif
+ db = query.value(0).toString();
+ }
+ else {
+ qDebug("Error select_01: %s (%s)",query.lastError().text().TOUTF8().data(),
+ query.lastQuery().TOUTF8().data());
+ }
+ if (!db.isEmpty()) {
+ QString fulldb = m_BasePath+"/"+db+".db";
+ QDataBase _db = QSqlDatabase::addDatabase(SQLTYPE,"tmpdb");
+#if QT_VERSION < 0x040000
+ _db->setDatabaseName(fulldb);
+#else
+ _db.setDatabaseName(fulldb);
+#endif
+ if (!checkReposDb(_db)) {
+ }
+ QSqlDatabase::removeDatabase("tmpdb");
+ }
+ return db;
+ }
+
+ QDataBase getReposDB(const svn::Path&reposroot) {
+#if QT_VERSION < 0x040000
+ if (!getMainDB()) {
+ return 0;
+#else
+ if (!getMainDB().isValid()) {
+ return QDataBase();
+#endif
+ }
+ bool checkDone = false;
+ // make sure path is correct eg. without traling slashes.
+ QString dbFile;
+ QSqlQuery c(QString::null,getMainDB());
+ c.prepare(s_reposSelect);
+ c.bindValue(0,reposroot.native());
+ c.exec();
+
+#if QT_VERSION < 0x040000
+ //qDebug("Check for path: "+reposroot.native());
+#endif
+
+ // only the first one
+ if ( c.next() ) {
+#if QT_VERSION < 0x040000
+/* qDebug( c.value(0).toString() + ": " +
+ c.value(0).toString() );*/
+#endif
+ dbFile = c.value(0).toString();
+ }
+ if (dbFile.isEmpty()) {
+ dbFile = createReposDB(reposroot);
+ if (dbFile.isEmpty()) {
+#if QT_VERSION < 0x040000
+ return 0;
+#else
+ return QSqlDatabase();
+#endif
+ }
+ checkDone=true;
+ }
+ if (m_mainDB.localData()->reposCacheNames.find(dbFile)!=m_mainDB.localData()->reposCacheNames.end()) {
+ return QSqlDatabase::database(m_mainDB.localData()->reposCacheNames[dbFile]);
+ }
+ int i = 0;
+ QString _key = dbFile;
+ while (QSqlDatabase::contains(_key)) {
+ _key = QString("%1-%2").arg(dbFile).arg(i++);
+ }
+// qDebug("The repository key is now: %s",_key.TOUTF8().data());
+ QDataBase _db = QSqlDatabase::addDatabase(SQLTYPE,_key);
+#if QT_VERSION < 0x040000
+ if (!_db) {
+ return 0;
+ }
+#endif
+ QString fulldb = m_BasePath+"/"+dbFile+".db";
+#if QT_VERSION < 0x040000
+ _db->setDatabaseName(fulldb);
+#else
+ _db.setDatabaseName(fulldb);
+#endif
+// qDebug("try database open %s",fulldb.TOUTF8().data());
+ if (!checkReposDb(_db)) {
+ qDebug("no DB opened");
+#if QT_VERSION < 0x040000
+ _db = 0;
+#else
+ _db = QSqlDatabase();
+#endif
+ } else {
+ qDebug("Insert into map");
+ m_mainDB.localData()->reposCacheNames[dbFile]=_key;
+ }
+ return _db;
+ }
+
+ QDataBase getMainDB()const
+ {
+ if (!m_mainDB.hasLocalData()) {
+ unsigned i=0;
+ QString _key = SQLMAIN;
+ while (QSqlDatabase::contains(_key)) {
+ _key.sprintf("%s-%i",SQLMAIN,i++);
+ }
+ qDebug("The key is now: %s",_key.TOUTF8().data());
+
+ QDataBase db = QSqlDatabase::addDatabase(SQLTYPE,_key);
+#if QT_VERSION < 0x040000
+ db->setDatabaseName(m_BasePath+"/maindb.db");
+ if (!db->open()) {
+#else
+ db.setDatabaseName(m_BasePath+"/maindb.db");
+ if (!db.open()) {
+#endif
+#if QT_VERSION < 0x040000
+ qWarning("Failed to open main database: " + db->lastError().text());
+#endif
+ } else {
+ m_mainDB.setLocalData(new ThreadDBStore);
+ m_mainDB.localData()->key = _key;
+ m_mainDB.localData()->m_DB = db;
+ }
+ }
+ if (m_mainDB.hasLocalData()) {
+ return m_mainDB.localData()->m_DB;
+ } else {
+#if QT_VERSION < 0x040000
+ return 0;
+#else
+ return QSqlDatabase();
+#endif
+ }
+ }
+ QString m_BasePath;
+
+ mutable QThreadStorage<ThreadDBStore*> m_mainDB;
+
+ static const QString s_reposSelect;
+};
+
+
+QString LogCache::s_CACHE_FOLDER="logcache";
+const QString LogCacheData::s_reposSelect=QString("SELECT id from ")+QString(SQLMAINTABLE)+QString(" where reposroot=? ORDER by id DESC");
+
+/*!
+ \fn svn::cache::LogCache::LogCache()
+ */
+LogCache::LogCache()
+{
+ m_BasePath = QDir::HOMEDIR()+"/.svnqt";
+ setupCachePath();
+}
+
+LogCache::LogCache(const QString&aBasePath)
+{
+ if (mSelf) {
+ delete mSelf;
+ }
+ mSelf=this;
+ if (aBasePath.isEmpty()) {
+ m_BasePath=QDir::HOMEDIR()+"/.svnqt";
+ } else {
+ m_BasePath=aBasePath;
+ }
+ setupCachePath();
+}
+
+
+LogCache::~LogCache()
+{
+}
+
+/*!
+ \fn svn::cache::LogCache::setupCachePath()
+ */
+void LogCache::setupCachePath()
+{
+ m_CacheData = new LogCacheData;
+ m_CacheData->m_BasePath=m_BasePath;
+ QDir d;
+ if (!d.exists(m_BasePath)) {
+ d.mkdir(m_BasePath);
+ }
+ m_BasePath=m_BasePath+"/"+s_CACHE_FOLDER;
+ if (!d.exists(m_BasePath)) {
+ d.mkdir(m_BasePath);
+ }
+ m_CacheData->m_BasePath=m_BasePath;
+ if (d.exists(m_BasePath)) {
+ setupMainDb();
+ }
+}
+
+void LogCache::setupMainDb()
+{
+#ifndef NO_SQLITE3
+ if (!QSqlDatabase::isDriverAvailable(SQLTYPE)) {
+ QSqlDatabase::registerSqlDriver(SQLTYPE,new QSqlDriverCreator<QSQLite3Driver>);
+ }
+#endif
+ QDataBase mainDB = m_CacheData->getMainDB();
+#if QT_VERSION < 0x040000
+ if (!mainDB || !mainDB->open()) {
+ qWarning("Failed to open main database: " + (mainDB?mainDB->lastError().text():"No database object."));
+#else
+ if (!mainDB.isValid()) {
+ qWarning("Failed to open main database.");
+#endif
+ } else {
+ QSqlQuery q(QString::null, mainDB);
+#if QT_VERSION < 0x040000
+ mainDB->transaction();
+#else
+ mainDB.transaction();
+#endif
+ if (!q.exec("CREATE TABLE IF NOT EXISTS \""+QString(SQLMAINTABLE)+"\" (\"reposroot\" TEXT,\"id\" INTEGER PRIMARY KEY NOT NULL);")) {
+#if QT_VERSION < 0x040000
+ qWarning("Failed create main database: " + mainDB->lastError().text());
+#endif
+ }
+#if QT_VERSION < 0x040000
+ mainDB->commit();
+#else
+ mainDB.commit();
+#endif
+ }
+}
+
+}
+}
+
+
+/*!
+ \fn svn::cache::LogCache::self()
+ */
+svn::cache::LogCache* svn::cache::LogCache::self()
+{
+ if (!mSelf) {
+ mSelf=new LogCache();
+ }
+ return mSelf;
+}
+
+
+/*!
+ \fn svn::cache::LogCache::reposDb()
+ */
+QDataBase svn::cache::LogCache::reposDb(const QString&aRepository)
+{
+// qDebug("reposDB");
+ return m_CacheData->getReposDB(aRepository);
+}
+
+
+/*!
+ \fn svn::cache::LogCache::cachedRepositories()const
+ */
+QStringList svn::cache::LogCache::cachedRepositories()const
+{
+ static QString s_q(QString("select \"reposroot\" from ")+QString(SQLMAINTABLE)+QString("order by reposroot"));
+ QDataBase mainDB = m_CacheData->getMainDB();
+ QStringList _res;
+#if QT_VERSION < 0x040000
+ if (!mainDB || !mainDB->open()) {
+#else
+ if (!mainDB.isValid()) {
+#endif
+ qWarning("Failed to open main database.");
+ return _res;
+ }
+ QSqlQuery cur(QString::null,mainDB);
+ cur.prepare(s_q);
+ if (!cur.exec()) {
+ qDebug(cur.lastError().text().TOUTF8().data());
+ throw svn::cache::DatabaseException(QString("Could not retrieve values: ")+cur.lastError().text());
+ return _res;
+ }
+ while (cur.next()) {
+ _res.append(cur.value(0).toString());
+ }
+
+ return _res;
+}
+
+bool svn::cache::LogCache::valid()const
+{
+ QDataBase mainDB = m_CacheData->getMainDB();
+#if QT_VERSION < 0x040000
+ if (!mainDB || !mainDB->open()) {
+#else
+ if (!mainDB.isValid()) {
+#endif
+ return false;
+ }
+ return true;
+}
diff --git a/src/svnqt/cache/LogCache.hpp b/src/svnqt/cache/LogCache.hpp
new file mode 100644
index 0000000..9e76697
--- /dev/null
+++ b/src/svnqt/cache/LogCache.hpp
@@ -0,0 +1,41 @@
+#ifndef _LOG_CACHE_HPP
+#define _LOG_CACHE_HPP
+
+#include <qstring.h>
+#include <qdir.h>
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/shared_pointer.hpp"
+
+namespace svn {
+ namespace cache {
+
+ class LogCacheData;
+
+ class SVNQT_EXPORT LogCache
+ {
+ private:
+ svn::SharedPointer<LogCacheData> m_CacheData;
+
+ protected:
+ LogCache();
+ static LogCache* mSelf;
+ QString m_BasePath;
+ static QString s_CACHE_FOLDER;
+ void setupCachePath();
+ void setupMainDb();
+
+ public:
+ ///! should used for testing only!
+ LogCache(const QString&aBasePath);
+ virtual ~LogCache();
+ static LogCache* self();
+ QDataBase reposDb(const QString&aRepository);
+ QStringList cachedRepositories()const;
+
+ bool valid()const;
+ };
+ }
+}
+
+#endif
diff --git a/src/svnqt/cache/ReposLog.cpp b/src/svnqt/cache/ReposLog.cpp
new file mode 100644
index 0000000..89be2d0
--- /dev/null
+++ b/src/svnqt/cache/ReposLog.cpp
@@ -0,0 +1,535 @@
+#include "ReposLog.hpp"
+
+#include "LogCache.hpp"
+#include "svnqt/info_entry.hpp"
+#include "svnqt/svnqttypes.hpp"
+#include "svnqt/client.hpp"
+#include "svnqt/context_listener.hpp"
+#include "svnqt/cache/DatabaseException.hpp"
+
+#include <qsqldatabase.h>
+
+#if QT_VERSION < 0x040000
+#else
+#include <QSqlError>
+#include <QSqlQuery>
+#include <QVariant>
+#define Q_LLONG qlonglong
+#endif
+
+/*!
+ \fn svn::cache::ReposLog::ReposLog(svn::Client*aClient,const QString&)
+ */
+svn::cache::ReposLog::ReposLog(svn::Client*aClient,const QString&aRepository)
+ :m_Client(),
+#if QT_VERSION < 0x040000
+ m_Database(0),
+#else
+ m_Database(),
+#endif
+ m_ReposRoot(aRepository),m_latestHead(svn::Revision::UNDEFINED)
+{
+ m_Client=aClient;
+ ContextP ctx = m_Client->getContext();
+ if (!aRepository.isEmpty()) {
+ m_Database = LogCache::self()->reposDb(aRepository);
+ }
+}
+
+
+/*!
+ \fn svn::cache::ReposLog::latestHeadRev()
+ */
+svn::Revision svn::cache::ReposLog::latestHeadRev()
+{
+ if (!m_Client||m_ReposRoot.isEmpty()) {
+ return svn::Revision::UNDEFINED;
+ }
+#if QT_VERSION < 0x040000
+ if (!m_Database) {
+#else
+ if (!m_Database.isValid()) {
+#endif
+ m_Database = LogCache::self()->reposDb(m_ReposRoot);
+#if QT_VERSION < 0x040000
+ if (!m_Database) {
+#else
+ if (!m_Database.isValid()) {
+#endif
+ return svn::Revision::UNDEFINED;
+ }
+ }
+ /// no catch - exception has go trough...
+ qDebug("Getting headrev");
+ svn::InfoEntries e = m_Client->info(m_ReposRoot,svn::DepthEmpty,svn::Revision::HEAD,svn::Revision::HEAD);
+ if (e.count()<1||e[0].reposRoot().isEmpty()) {
+ return svn::Revision::UNDEFINED;
+ }
+ qDebug("Getting headrev done");
+ return e[0].revision();
+}
+
+
+/*!
+ \fn svn::cache::ReposLog::latestCachedRev()
+ */
+svn::Revision svn::cache::ReposLog::latestCachedRev()
+{
+ if (m_ReposRoot.isEmpty()) {
+ return svn::Revision::UNDEFINED;
+ }
+#if QT_VERSION < 0x040000
+ if (!m_Database) {
+#else
+ if (!m_Database.isValid()) {
+#endif
+ m_Database = LogCache::self()->reposDb(m_ReposRoot);
+#if QT_VERSION < 0x040000
+ if (!m_Database) {
+#else
+ if (!m_Database.isValid()) {
+#endif
+ return svn::Revision::UNDEFINED;
+ }
+ }
+ QString q("select revision from 'logentries' order by revision DESC limit 1");
+ QSqlQuery _q(QString::null, m_Database);
+ if (!_q.exec(q)) {
+ qDebug(_q.lastError().text().TOUTF8().data());
+ return svn::Revision::UNDEFINED;
+ }
+ int _r;
+ if (_q.isActive() && _q.next()) {
+ //qDebug("Sel result: %s",_q.value(0).toString().TOUTF8().data());
+ _r = _q.value(0).toInt();
+ } else {
+ qDebug(_q.lastError().text().TOUTF8().data());
+ return svn::Revision::UNDEFINED;
+ }
+ return _r;
+}
+
+bool svn::cache::ReposLog::checkFill(svn::Revision&start,svn::Revision&end,bool checkHead)
+{
+#if QT_VERSION < 0x040000
+ if (!m_Database) {
+#else
+ if (!m_Database.isValid()) {
+#endif
+ m_Database = LogCache::self()->reposDb(m_ReposRoot);
+#if QT_VERSION < 0x040000
+ if (!m_Database) {
+#else
+ if (!m_Database.isValid()) {
+#endif
+ return false;
+ }
+ }
+ ContextP cp = m_Client->getContext();
+ long long icount=0;
+
+ svn::Revision _latest=latestCachedRev();
+// qDebug("Latest cached rev: %i",_latest.revnum());
+// qDebug("End revision is: %s",end.toString().TOUTF8().data());
+
+ if (checkHead && _latest.revnum()>=latestHeadRev().revnum()) {
+ return true;
+ }
+
+ start=date2numberRev(start);
+ end=date2numberRev(end);
+
+ // both should now one of START, HEAD or NUMBER
+ if (start==svn::Revision::HEAD || (end==svn::Revision::NUMBER && start==svn::Revision::NUMBER && start.revnum()>end.revnum())) {
+ svn::Revision tmp = start;
+ start = end;
+ end = tmp;
+ }
+ svn::Revision _rstart=_latest.revnum()+1;
+ svn::Revision _rend = end;
+ if (_rend==svn::Revision::UNDEFINED) {
+// qDebug("Setting end to Head");
+ _rend=svn::Revision::HEAD;
+ }
+ // no catch - exception should go outside.
+ if (_rstart==0){
+ _rstart = 1;
+ }
+// qDebug("Getting log %s -> %s",_rstart.toString().TOUTF8().data(),_rend.toString().TOUTF8().data());
+ if (_rend==svn::Revision::HEAD) {
+ _rend=latestHeadRev();
+ }
+
+ if (_rend==svn::Revision::HEAD||_rend.revnum()>_latest.revnum()) {
+ LogEntriesMap _internal;
+// qDebug("Retrieving from network.");
+ if (!m_Client->log(m_ReposRoot,_rstart,_rend,_internal,svn::Revision::UNDEFINED,true,false)) {
+ return false;
+ }
+ LogEntriesMap::ConstIterator it=_internal.begin();
+
+ for (;it!=_internal.end();++it) {
+ _insertLogEntry((*it));
+ if (cp && cp->getListener()) {
+ //cp->getListener()->contextProgress(++icount,_internal.size());
+ if (cp->getListener()->contextCancel()) {
+ throw DatabaseException(QString("Could not retrieve values: User cancel."));
+ }
+ }
+ }
+ }
+ return true;
+}
+
+bool svn::cache::ReposLog::fillCache(const svn::Revision&_end)
+{
+ svn::Revision end = _end;
+ svn::Revision start = latestCachedRev().revnum()+1;
+ return checkFill(start,end,false);
+}
+
+/*!
+ \fn svn::cache::ReposLog::simpleLog(const svn::Revision&start,const svn::Revision&end,LogEntriesMap&target)
+ */
+bool svn::cache::ReposLog::simpleLog(LogEntriesMap&target,const svn::Revision&_start,const svn::Revision&_end,bool noNetwork)
+{
+ if (!m_Client||m_ReposRoot.isEmpty()) {
+ return false;
+ }
+ target.clear();
+ ContextP cp = m_Client->getContext();
+
+ svn::Revision end = _end;
+ svn::Revision start = _start;
+ if (!noNetwork) {
+ if (!checkFill(start,end,true)) {
+ return false;
+ }
+ } else {
+ end=date2numberRev(end,noNetwork);
+ start=date2numberRev(start,noNetwork);
+ }
+
+ if (end==svn::Revision::HEAD) {
+ end = latestCachedRev();
+ }
+ if (start==svn::Revision::HEAD) {
+ start=latestCachedRev();
+ }
+ static QString sCount("select count(*) from logentries where revision<=? and revision>=?");
+ static QString sEntry("select revision,author,date,message from logentries where revision<=? and revision>=?");
+ static QString sItems("select changeditem,action,copyfrom,copyfromrev from changeditems where revision=?");
+
+ QSqlQuery bcount(QString::null,m_Database);
+ bcount.prepare(sCount);
+
+ QSqlQuery bcur(QString::null,m_Database);
+ bcur.prepare(sEntry);
+
+ QSqlQuery cur(QString::null,m_Database);
+ cur.prepare(sItems);
+
+ bcount.bindValue(0,Q_LLONG(end.revnum()));
+ bcount.bindValue(1,Q_LLONG(start.revnum()));
+ if (!bcount.exec()) {
+ qDebug(bcount.lastError().text().TOUTF8().data());
+ throw svn::cache::DatabaseException(QString("Could not retrieve count: ")+bcount.lastError().text());
+ return false;
+ }
+ bcount.next();
+ if (bcount.value(0).toLongLong()<1) {
+ // we didn't found logs with this parameters
+ return false;
+ }
+
+ bcur.bindValue(0,Q_LLONG(end.revnum()));
+ bcur.bindValue(1,Q_LLONG(start.revnum()));
+
+ if (!bcur.exec()) {
+ qDebug(bcur.lastError().text().TOUTF8().data());
+ throw svn::cache::DatabaseException(QString("Could not retrieve values: ")+bcur.lastError().text());
+ return false;
+ }
+ Q_LLONG revision;
+ while(bcur.next()) {
+ revision = bcur.value(0).toLongLong();
+ cur.bindValue(0,revision);
+ if (!cur.exec()) {
+ qDebug(cur.lastError().text().TOUTF8().data());
+ throw svn::cache::DatabaseException(QString("Could not retrieve values: ")+cur.lastError().text()
+ ,cur.lastError().number());
+ return false;
+ }
+ target[revision].revision=revision;
+ target[revision].author=bcur.value(1).toString();
+ target[revision].date=bcur.value(2).toLongLong();
+ target[revision].message=bcur.value(3).toString();
+ while(cur.next()) {
+ LogChangePathEntry lcp;
+ QString ac = cur.value(1).toString();
+#if QT_VERSION < 0x040000
+ lcp.action=ac[0].latin1();
+#else
+ lcp.action=ac[0].toLatin1();
+#endif
+ lcp.copyFromPath=cur.value(2).toString();
+ lcp.path= cur.value(0).toString();
+ lcp.copyFromRevision=cur.value(3).toLongLong();
+ target[revision].changedPaths.push_back(lcp);
+ }
+ if (cp && cp->getListener()) {
+ if (cp->getListener()->contextCancel()) {
+ throw svn::cache::DatabaseException(QString("Could not retrieve values: User cancel."));
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+
+/*!
+ \fn svn::cache::ReposLog::date2numberRev(const svn::Revision&)
+ */
+svn::Revision svn::cache::ReposLog::date2numberRev(const svn::Revision&aRev,bool noNetwork)
+{
+ if (aRev!=svn::Revision::DATE) {
+ return aRev;
+ }
+#if QT_VERSION < 0x040000
+ if (!m_Database) {
+#else
+ if (!m_Database.isValid()) {
+#endif
+ return svn::Revision::UNDEFINED;
+ }
+ static QString _q("select revision from logentries where date<? order by revision desc");
+ QSqlQuery query("select revision,date from logentries order by revision desc limit 1",m_Database);
+
+#if QT_VERSION < 0x040000
+ if (query.lastError().type()!=QSqlError::None) {
+#else
+ if (query.lastError().type()!=QSqlError::NoError) {
+#endif
+ qDebug(query.lastError().text().TOUTF8().data());
+ }
+ bool must_remote=!noNetwork;
+ if (query.next()) {
+ if (query.value(1).toLongLong()>=aRev.date()) {
+ must_remote=false;
+ }
+ }
+ if (must_remote) {
+ svn::InfoEntries e = (m_Client->info(m_ReposRoot,svn::DepthEmpty,aRev,aRev));;
+ if (e.count()<1||e[0].reposRoot().isEmpty()) {
+ return aRev;
+ }
+ return e[0].revision();
+ }
+ query.prepare(_q);
+ query.bindValue(0,Q_LLONG(aRev.date()));
+ query.exec();
+#if QT_VERSION < 0x040000
+ if (query.lastError().type()!=QSqlError::None) {
+#else
+ if (query.lastError().type()!=QSqlError::NoError) {
+#endif
+ qDebug(query.lastError().text().TOUTF8().data());
+ }
+ if (query.next()) {
+ return query.value(0).toInt();
+ }
+ // not found...
+ if (noNetwork) {
+ return svn::Revision::UNDEFINED;
+ }
+ svn::InfoEntries e = (m_Client->info(m_ReposRoot,svn::DepthEmpty,svn::Revision::HEAD,svn::Revision::HEAD));;
+ if (e.count()<1||e[0].reposRoot().isEmpty()) {
+ return svn::Revision::UNDEFINED;
+ }
+ return e[0].revision();
+}
+
+
+/*!
+ \fn svn::cache::ReposLog::insertLogEntry(const svn::LogEntry&)
+ */
+bool svn::cache::ReposLog::_insertLogEntry(const svn::LogEntry&aEntry)
+{
+ QSqlRecord *buffer;
+
+#if QT_VERSION < 0x040000
+ m_Database->transaction();
+ Q_LLONG j = aEntry.revision;
+#else
+ m_Database.transaction();
+ qlonglong j = aEntry.revision;
+#endif
+ static QString qEntry("insert into logentries (revision,date,author,message) values (?,?,?,?)");
+ static QString qPathes("insert into changeditems (revision,changeditem,action,copyfrom,copyfromrev) values (?,?,?,?,?)");
+ QSqlQuery _q(QString::null,m_Database);
+ _q.prepare(qEntry);
+ _q.bindValue(0,j);
+ _q.bindValue(1,aEntry.date);
+ _q.bindValue(2,aEntry.author);
+ _q.bindValue(3,aEntry.message);
+ if (!_q.exec()) {
+#if QT_VERSION < 0x040000
+ m_Database->rollback();
+#else
+ m_Database.rollback();
+#endif
+ qDebug("Could not insert values: %s",_q.lastError().text().TOUTF8().data());
+ qDebug(_q.lastQuery().TOUTF8().data());
+ throw svn::cache::DatabaseException(QString("Could not insert values: ")+_q.lastError().text(),_q.lastError().number());
+ }
+ _q.prepare(qPathes);
+ svn::LogChangePathEntries::ConstIterator cpit = aEntry.changedPaths.begin();
+ for (;cpit!=aEntry.changedPaths.end();++cpit){
+ _q.bindValue(0,j);
+ _q.bindValue(1,(*cpit).path);
+ _q.bindValue(2,QString(QChar((*cpit).action)));
+ _q.bindValue(3,(*cpit).copyFromPath);
+ _q.bindValue(4,Q_LLONG((*cpit).copyFromRevision));
+ if (!_q.exec()) {
+#if QT_VERSION < 0x040000
+ m_Database->rollback();
+#else
+ m_Database.rollback();
+#endif
+ qDebug("Could not insert values: %s",_q.lastError().text().TOUTF8().data());
+ qDebug(_q.lastQuery().TOUTF8().data());
+ throw svn::cache::DatabaseException(QString("Could not insert values: ")+_q.lastError().text(),_q.lastError().number());
+ }
+ }
+#if QT_VERSION < 0x040000
+ m_Database->commit();
+#else
+ m_Database.commit();
+#endif
+ return true;
+}
+
+bool svn::cache::ReposLog::insertLogEntry(const svn::LogEntry&aEntry)
+{
+ return _insertLogEntry(aEntry);
+}
+
+
+/*!
+ \fn svn::cache::ReposLog::log(const svn::Path&,const svn::Revision&start, const svn::Revision&end,const svn::Revision&peg,svn::LogEntriesMap&target, bool strictNodeHistory,int limit))
+ */
+bool svn::cache::ReposLog::log(const svn::Path&what,const svn::Revision&_start, const svn::Revision&_end,const svn::Revision&_peg,svn::LogEntriesMap&target, bool strictNodeHistory,int limit)
+{
+ static QString s_q("select logentries.revision,logentries.author,logentries.date,logentries.message from logentries where logentries.revision in (select changeditems.revision from changeditems where (changeditems.changeditem='%1' or changeditems.changeditem GLOB '%2/*') %3 GROUP BY changeditems.revision) ORDER BY logentries.revision DESC");
+
+ static QString s_e("select changeditem,action,copyfrom,copyfromrev from changeditems where changeditems.revision='%1'");
+
+ svn::Revision peg = date2numberRev(_peg,true);
+ svn::Revision end = date2numberRev(_end,true);
+ svn::Revision start = date2numberRev(_start,true);
+ QString query_string = QString(s_q).arg(what.native()).arg(what.native()).arg((peg==svn::Revision::UNDEFINED?"":QString(" AND revision<=%1").arg(peg.revnum())));
+ if (peg==svn::Revision::UNDEFINED) {
+ peg = latestCachedRev();
+ }
+ if (!itemExists(peg,what)) {
+ throw svn::cache::DatabaseException(QString("Entry '%1' does not exists at revision %2").arg(what.native()).arg(peg.toString()));
+ }
+ if (limit>0) {
+ query_string+=QString(" LIMIT %1").arg(limit);
+ }
+ QSqlQuery _q(QString::null,m_Database);
+ QSqlQuery _q2(QString::null,m_Database);
+ _q.prepare(query_string);
+ if (!_q.exec()) {
+ qDebug("Could not select values: %s",_q.lastError().text().TOUTF8().data());
+ qDebug(_q.lastQuery().TOUTF8().data());
+ throw svn::cache::DatabaseException(QString("Could not select values: ")+_q.lastError().text(),_q.lastError().number());
+ }
+ while(_q.next()) {
+ Q_LLONG revision = _q.value(0).toLongLong();
+ target[revision].revision=revision;
+ target[revision].author=_q.value(1).toString();
+ target[revision].date=_q.value(2).toLongLong();
+ target[revision].message=_q.value(3).toString();
+ query_string=s_e.arg(revision);
+ _q2.prepare(query_string);
+ if (!_q2.exec()) {
+ qDebug("Could not select values: %s",_q2.lastError().text().TOUTF8().data());
+ } else {
+ while (_q2.next()) {
+#if QT_VERSION < 0x040000
+ target[revision].changedPaths.push_back (
+ LogChangePathEntry (_q2.value(0).toString(),
+ _q2.value(1).toString()[0],
+ _q2.value(2).toString(),
+ _q2.value(3).toLongLong()
+ )
+ );
+#else
+ target[revision].changedPaths.push_back (
+ LogChangePathEntry (_q2.value(0).toString(),
+ _q2.value(1).toChar().toLatin1(),
+ _q2.value(2).toString(),
+ _q2.value(3).toLongLong()
+ )
+ );
+#endif
+ }
+ }
+
+ }
+ return true;
+}
+
+
+/*!
+ \fn svn::cache::ReposLog::itemExists(const svn::Revision&,const QString&)
+ */
+bool svn::cache::ReposLog::itemExists(const svn::Revision&peg,const svn::Path&path)
+{
+ /// @todo this moment I have no idea how to check real with all moves and deletes of parent folders without a hell of sql statements so we make it quite simple: it exists if we found it.
+
+
+#if 0
+ static QString _s1("select revision from changeditems where changeditem='%1' and action='A' and revision<=%2 order by revision desc limit 1");
+ QSqlQuery _q(QString::null,m_Database);
+ QString query_string=QString(_s1).arg(path.native()).arg(peg.revnum());
+ if (!_q.exec(query_string)) {
+ qDebug("Could not select values: %s",_q.lastError().text().TOUTF8().data());
+ qDebug(_q.lastQuery().TOUTF8().data());
+ throw svn::cache::DatabaseException(QString("Could not select values: ")+_q.lastError().text(),_q.lastError().number());
+ }
+ qDebug(_q.lastQuery().TOUTF8().data());
+
+
+ svn::Path _p = path;
+ static QString _s2("select revision from changeditem where changeditem in (%1) and action='D' and revision>%2 and revision<=%3 order by revision desc limit 1");
+ QStringList p_list;
+ while (_p.length()>0) {
+ p_list.append(QString("'%1'").arg(_p.native()));
+ _p.removeLast();
+ }
+ query_string=QString(_s2).arg(p_list.join(",")).arg();
+#endif
+ return true;
+}
+
+bool svn::cache::ReposLog::isValid()const
+{
+#if QT_VERSION < 0x040000
+ if (!m_Database) {
+#else
+ if (!m_Database.isValid()) {
+#endif
+ m_Database = LogCache::self()->reposDb(m_ReposRoot);
+#if QT_VERSION < 0x040000
+ if (!m_Database) {
+#else
+ if (!m_Database.isValid()) {
+#endif
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/src/svnqt/cache/ReposLog.hpp b/src/svnqt/cache/ReposLog.hpp
new file mode 100644
index 0000000..e81a5c9
--- /dev/null
+++ b/src/svnqt/cache/ReposLog.hpp
@@ -0,0 +1,70 @@
+#ifndef _REPOS_LOG_HPP
+#define _REPOS_LOG_HPP
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/svnqttypes.hpp"
+#include "svnqt/revision.hpp"
+
+#include <qsqldatabase.h>
+#include <qstring.h>
+
+namespace svn
+{
+
+class Client;
+
+namespace cache
+{
+
+class SVNQT_EXPORT ReposLog
+{
+protected:
+ svn::Client*m_Client;
+ mutable QDataBase m_Database;
+ QString m_ReposRoot;
+ svn::Revision m_latestHead;
+ //! internal insert.
+ bool _insertLogEntry(const svn::LogEntry&);
+ bool checkFill(svn::Revision&_start,svn::Revision&_end,bool checkHead);
+
+public:
+ ReposLog(svn::Client*aClient,const QString&aRepository=QString::null);
+
+ QString ReposRoot() const
+ {
+ return m_ReposRoot;
+ }
+
+ QDataBase Database() const
+ {
+ return m_Database;
+ }
+ //! search for latest head revision on network for assigned repository
+ svn::Revision latestHeadRev();
+ //! return lates revision in cache
+ svn::Revision latestCachedRev();
+ //! simple retrieves logentries
+ /*!
+ * This method acts on network, too for checking if there are new entries on server.
+ *
+ * @param target where to store the result
+ * @param start revision to start for search
+ * @param end revision to end for search
+ * @param noNetwork if yes, no check on network for newer revisions will made
+ * @return true if entries found and no error, if no entries found false
+ * @exception svn::DatabaseException in case of errors
+ */
+ bool simpleLog(LogEntriesMap&target,const svn::Revision&start,const svn::Revision&end,bool noNetwork=false);
+ svn::Revision date2numberRev(const svn::Revision&,bool noNetwork=false);
+ bool fillCache(const svn::Revision&end);
+ bool insertLogEntry(const svn::LogEntry&);
+ bool log(const svn::Path&,const svn::Revision&start, const svn::Revision&end,const svn::Revision&peg,svn::LogEntriesMap&target, bool strictNodeHistory,int limit);
+ bool itemExists(const svn::Revision&,const svn::Path&);
+
+ bool isValid()const;
+};
+
+}
+}
+
+#endif
diff --git a/src/svnqt/cache/sqlite3/README b/src/svnqt/cache/sqlite3/README
new file mode 100644
index 0000000..e2f7914
--- /dev/null
+++ b/src/svnqt/cache/sqlite3/README
@@ -0,0 +1,32 @@
+With this driver you can access the files created by sqlite3 through
+the standard Qt sql module. The driver name is QSQLITE3.
+
+Although there are many other solutions to access such DB files, I think
+that using this driver has some advantages:
+
+--> You use the standard Qt interface so you can reuse exinting code or
+ switch to or from other DB types quite easily.
+
+--> Soft transition to Qt 4: Qt 4 supports sqlite3, you can prepare your
+ application now.
+
+--> The source of this driver is smaller than any other, you can incorporate
+ it on your application with little overhead and without requiring external
+ libraries.
+
+
+Developer note:
+
+The driver is a merge between the QSQLITE driver in Qt 3 and in Qt 4 beta 1, with
+small tweaks, so I think is quite stable and usable.
+Please report success or failure, thanks
+
+To compile
+
+qmake
+make
+cp sqldrivers/libqsqlite3.so $QTDIR/plugins/sqldrivers (probably as root)
+
+use it as any other Qt sql driver.
+
+Have fun, Stefano !!! \ No newline at end of file
diff --git a/src/svnqt/cache/sqlite3/qsql_sqlite3.cpp b/src/svnqt/cache/sqlite3/qsql_sqlite3.cpp
new file mode 100644
index 0000000..93010c1
--- /dev/null
+++ b/src/svnqt/cache/sqlite3/qsql_sqlite3.cpp
@@ -0,0 +1,485 @@
+/****************************************************************************
+**
+** Implementation of SQLite driver classes.
+**
+** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
+**
+** This file is part of the sql module of the Qt GUI Toolkit.
+** EDITIONS: FREE, ENTERPRISE
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "qsql_sqlite3.h"
+
+#include <qdatetime.h>
+#include <qvaluevector.h>
+#include <qregexp.h>
+#include <qfile.h>
+#include <sqlite3.h>
+
+#if (QT_VERSION-0 < 0x030200)
+# include <qvector.h>
+# if !defined Q_WS_WIN32
+# include <unistd.h>
+# endif
+#else
+# include <qptrvector.h>
+# if !defined Q_WS_WIN32
+# include <unistd.h>
+# endif
+#endif
+
+typedef struct sqlite3_stmt sqlite3_stmt;
+
+#define QSQLITE3_DRIVER_NAME "QSQLITE3"
+
+static QVariant::Type qSqliteType(int tp)
+{
+ switch (tp) {
+ case SQLITE_INTEGER:
+ return QVariant::Int;
+ case SQLITE_FLOAT:
+ return QVariant::Double;
+ case SQLITE_BLOB:
+ return QVariant::ByteArray;
+ case SQLITE_TEXT:
+ default:
+ return QVariant::String;
+ }
+}
+
+static QSqlError qMakeError(sqlite3 *access, const QString &descr, QSqlError::Type type,
+ int errorCode = -1)
+{
+ return QSqlError(descr,
+ QString::fromUtf8(sqlite3_errmsg(access)),
+ type, errorCode);
+}
+
+class QSQLite3DriverPrivate
+{
+public:
+ QSQLite3DriverPrivate();
+ sqlite3 *access;
+ bool utf8;
+};
+
+QSQLite3DriverPrivate::QSQLite3DriverPrivate() : access(0)
+{
+ utf8 = true;
+}
+
+class QSQLite3ResultPrivate
+{
+public:
+ QSQLite3ResultPrivate(QSQLite3Result *res);
+ void cleanup();
+ bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
+ bool isSelect();
+ // initializes the recordInfo and the cache
+ void initColumns();
+ void finalize();
+
+ QSQLite3Result* q;
+ sqlite3 *access;
+
+ sqlite3_stmt *stmt;
+
+ uint skippedStatus: 1; // the status of the fetchNext() that's skipped
+ uint skipRow: 1; // skip the next fetchNext()?
+ uint utf8: 1;
+ QSqlRecord rInf;
+};
+
+static const uint initial_cache_size = 128;
+
+QSQLite3ResultPrivate::QSQLite3ResultPrivate(QSQLite3Result* res) : q(res), access(0),
+ stmt(0), skippedStatus(false), skipRow(false), utf8(false)
+{
+}
+
+void QSQLite3ResultPrivate::cleanup()
+{
+ finalize();
+ rInf.clear();
+ skippedStatus = false;
+ skipRow = false;
+ q->setAt(QSql::BeforeFirst);
+ q->setActive(false);
+ q->cleanup();
+}
+
+void QSQLite3ResultPrivate::finalize()
+{
+ if (!stmt)
+ return;
+
+ sqlite3_finalize(stmt);
+ stmt = 0;
+}
+
+// called on first fetch
+void QSQLite3ResultPrivate::initColumns()
+{
+ rInf.clear();
+
+ int nCols = sqlite3_column_count(stmt);
+ if (nCols <= 0)
+ return;
+
+ q->init(nCols);
+
+ for (int i = 0; i < nCols; ++i) {
+ QString colName = QString::fromUtf8(sqlite3_column_name(stmt, i));
+
+ int dotIdx = colName.findRev('.');
+ rInf.append(QSqlField(colName.mid(dotIdx == -1 ? 0 : dotIdx + 1),
+ qSqliteType(sqlite3_column_type(stmt, i))));
+ }
+}
+
+bool QSQLite3ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch)
+{
+ int res;
+ unsigned int i;
+
+ if (skipRow) {
+ // already fetched
+ Q_ASSERT(!initialFetch);
+ skipRow = false;
+ return skippedStatus;
+ }
+ skipRow = initialFetch;
+
+ if (!stmt)
+ return false;
+
+ // keep trying while busy, wish I could implement this better.
+ while ((res = sqlite3_step(stmt)) == SQLITE_BUSY) {
+ // sleep instead requesting result again immidiately.
+#if defined Q_OS_WIN
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+ }
+
+ switch(res) {
+ case SQLITE_ROW:
+ // check to see if should fill out columns
+ if (rInf.isEmpty())
+ // must be first call.
+ initColumns();
+ if (idx < 0 && !initialFetch)
+ return true;
+ for (i = 0; i < rInf.count(); ++i)
+ // todo - handle other types
+ values[i + idx] = QString::fromUtf8((char *)(sqlite3_column_text(stmt, i)));
+ // values[i + idx] = utf8 ? QString::fromUtf8(fvals[i]) : QString::fromAscii(fvals[i]);
+ return true;
+ case SQLITE_DONE:
+ if (rInf.isEmpty())
+ // must be first call.
+ initColumns();
+ q->setAt(QSql::AfterLast);
+ return false;
+ case SQLITE_ERROR:
+ case SQLITE_MISUSE:
+ default:
+ // something wrong, don't get col info, but still return false
+ q->setLastError(qMakeError(access, "Unable to fetch row", QSqlError::Connection, res));
+ finalize();
+ q->setAt(QSql::AfterLast);
+ return false;
+ }
+ return false;
+}
+
+QSQLite3Result::QSQLite3Result(const QSQLite3Driver* db)
+ : QSqlCachedResult(db)
+{
+ d = new QSQLite3ResultPrivate(this);
+ d->access = db->d->access;
+}
+
+QSQLite3Result::~QSQLite3Result()
+{
+ d->cleanup();
+ delete d;
+}
+
+/*
+ Execute \a query.
+*/
+bool QSQLite3Result::reset (const QString &query)
+{
+ // this is where we build a query.
+ if (!driver() || !driver()->isOpen() || driver()->isOpenError())
+ return false;
+
+ d->cleanup();
+
+ setSelect(false);
+
+ int res = sqlite3_prepare(d->access, query.utf8().data(), (query.length() + 1) * sizeof(QChar),
+ &d->stmt, 0);
+
+ if (res != SQLITE_OK) {
+ setLastError(qMakeError(d->access, "Unable to execute statement", QSqlError::Statement, res));
+ d->finalize();
+ return false;
+ }
+
+ d->skippedStatus = d->fetchNext(cache(), 0, true);
+
+ setSelect(!d->rInf.isEmpty());
+ setActive(true);
+ return true;
+}
+
+bool QSQLite3Result::gotoNext(QSqlCachedResult::ValueCache& row, int idx)
+{
+ return d->fetchNext(row, idx, false);
+}
+
+int QSQLite3Result::size()
+{
+ return -1;
+}
+
+int QSQLite3Result::numRowsAffected()
+{
+ return sqlite3_changes(d->access);
+}
+
+/////////////////////////////////////////////////////////
+
+QSQLite3Driver::QSQLite3Driver(QObject * parent, const char *name)
+ : QSqlDriver(parent, name)
+{
+ d = new QSQLite3DriverPrivate();
+}
+
+QSQLite3Driver::QSQLite3Driver(sqlite3 *connection, QObject *parent, const char *name)
+ : QSqlDriver(parent, name)
+{
+ d = new QSQLite3DriverPrivate();
+ d->access = connection;
+ setOpen(true);
+ setOpenError(false);
+}
+
+
+QSQLite3Driver::~QSQLite3Driver()
+{
+ delete d;
+}
+
+bool QSQLite3Driver::hasFeature(DriverFeature f) const
+{
+ switch (f) {
+ case Transactions:
+ case Unicode:
+ case BLOB:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*
+ SQLite dbs have no user name, passwords, hosts or ports.
+ just file names.
+*/
+bool QSQLite3Driver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &)
+{
+ if (isOpen())
+ close();
+
+ if (db.isEmpty())
+ return false;
+
+ if (sqlite3_open(QFile::encodeName(db), &d->access) == SQLITE_OK) {
+ setOpen(true);
+ setOpenError(false);
+ return true;
+ } else {
+ setLastError(qMakeError(d->access, "Error opening database",
+ QSqlError::Connection));
+ setOpenError(true);
+ return false;
+ }
+}
+
+void QSQLite3Driver::close()
+{
+ if (isOpen()) {
+ if (sqlite3_close(d->access) != SQLITE_OK)
+ setLastError(qMakeError(d->access, "Error closing database",
+ QSqlError::Connection));
+ d->access = 0;
+ setOpen(false);
+ setOpenError(false);
+ }
+}
+
+QSqlQuery QSQLite3Driver::createQuery() const
+{
+ return QSqlQuery(new QSQLite3Result(this));
+}
+
+bool QSQLite3Driver::beginTransaction()
+{
+ if (!isOpen() || isOpenError())
+ return false;
+
+ QSqlQuery q(createQuery());
+ if (!q.exec("BEGIN")) {
+ setLastError(QSqlError("Unable to begin transaction",
+ q.lastError().databaseText(), QSqlError::Transaction));
+ return false;
+ }
+
+ return true;
+}
+
+bool QSQLite3Driver::commitTransaction()
+{
+ if (!isOpen() || isOpenError())
+ return false;
+
+ QSqlQuery q(createQuery());
+ if (!q.exec("COMMIT")) {
+ setLastError(QSqlError("Unable to begin transaction",
+ q.lastError().databaseText(), QSqlError::Transaction));
+ return false;
+ }
+
+ return true;
+}
+
+bool QSQLite3Driver::rollbackTransaction()
+{
+ if (!isOpen() || isOpenError())
+ return false;
+
+ QSqlQuery q(createQuery());
+ if (!q.exec("ROLLBACK")) {
+ setLastError(QSqlError("Unable to begin transaction",
+ q.lastError().databaseText(), QSqlError::Transaction));
+ return false;
+ }
+
+ return true;
+}
+
+QStringList QSQLite3Driver::tables(const QString &typeName) const
+{
+ QStringList res;
+ if (!isOpen())
+ return res;
+ int type = typeName.toInt();
+
+ QSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+#if (QT_VERSION-0 >= 0x030200)
+ if ((type & (int)QSql::Tables) && (type & (int)QSql::Views))
+ q.exec("SELECT name FROM sqlite_master WHERE type='table' OR type='view'");
+ else if (typeName.isEmpty() || (type & (int)QSql::Tables))
+ q.exec("SELECT name FROM sqlite_master WHERE type='table'");
+ else if (type & (int)QSql::Views)
+ q.exec("SELECT name FROM sqlite_master WHERE type='view'");
+#else
+ q.exec("SELECT name FROM sqlite_master WHERE type='table' OR type='view'");
+#endif
+
+
+ if (q.isActive()) {
+ while(q.next())
+ res.append(q.value(0).toString());
+ }
+
+#if (QT_VERSION-0 >= 0x030200)
+ if (type & (int)QSql::SystemTables) {
+ // there are no internal tables beside this one:
+ res.append("sqlite_master");
+ }
+#endif
+
+ return res;
+}
+
+QSqlIndex QSQLite3Driver::primaryIndex(const QString &tblname) const
+{
+ QSqlRecordInfo rec(recordInfo(tblname)); // expensive :(
+
+ if (!isOpen())
+ return QSqlIndex();
+
+ QSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+ // finrst find a UNIQUE INDEX
+ q.exec("PRAGMA index_list('" + tblname + "');");
+ QString indexname;
+ while(q.next()) {
+ if (q.value(2).toInt()==1) {
+ indexname = q.value(1).toString();
+ break;
+ }
+ }
+ if (indexname.isEmpty())
+ return QSqlIndex();
+
+ q.exec("PRAGMA index_info('" + indexname + "');");
+
+ QSqlIndex index(indexname);
+ while(q.next()) {
+ QString name = q.value(2).toString();
+ QSqlVariant::Type type = QSqlVariant::Invalid;
+ if (rec.contains(name))
+ type = rec.find(name).type();
+ index.append(QSqlField(name, type));
+ }
+ return index;
+}
+
+QSqlRecordInfo QSQLite3Driver::recordInfo(const QString &tbl) const
+{
+ if (!isOpen())
+ return QSqlRecordInfo();
+
+ QSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+ q.exec("SELECT * FROM " + tbl + " LIMIT 1");
+ return recordInfo(q);
+}
+
+QSqlRecord QSQLite3Driver::record(const QString &tblname) const
+{
+ if (!isOpen())
+ return QSqlRecord();
+
+ return recordInfo(tblname).toRecord();
+}
+
+QSqlRecord QSQLite3Driver::record(const QSqlQuery& query) const
+{
+ if (query.isActive() && query.driver() == this) {
+ QSQLite3Result* result = (QSQLite3Result*)query.result();
+ return result->d->rInf;
+ }
+ return QSqlRecord();
+}
+
+QSqlRecordInfo QSQLite3Driver::recordInfo(const QSqlQuery& query) const
+{
+ if (query.isActive() && query.driver() == this) {
+ QSQLite3Result* result = (QSQLite3Result*)query.result();
+ return QSqlRecordInfo(result->d->rInf);
+ }
+ return QSqlRecordInfo();
+}
diff --git a/src/svnqt/cache/sqlite3/qsql_sqlite3.h b/src/svnqt/cache/sqlite3/qsql_sqlite3.h
new file mode 100644
index 0000000..f89c038
--- /dev/null
+++ b/src/svnqt/cache/sqlite3/qsql_sqlite3.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Definition of SQLite driver classes.
+**
+** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
+**
+** This file is part of the sql module of the Qt GUI Toolkit.
+** EDITIONS: FREE, ENTERPRISE
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef QSQL_SQLITE3_H
+#define QSQL_SQLITE3_H
+
+#include <qsqldriver.h>
+#include <qsqlresult.h>
+#include <qsqlrecord.h>
+#include <qsqlindex.h>
+#include "qsqlcachedresult.h"
+
+#if (QT_VERSION-0 >= 0x030200)
+typedef QVariant QSqlVariant;
+#endif
+
+#if defined (Q_OS_WIN32)
+# include <qt_windows.h>
+#endif
+
+class QSQLite3DriverPrivate;
+class QSQLite3ResultPrivate;
+class QSQLite3Driver;
+struct sqlite3;
+
+class QSQLite3Result : public QSqlCachedResult
+{
+ friend class QSQLite3Driver;
+ friend class QSQLite3ResultPrivate;
+public:
+ QSQLite3Result(const QSQLite3Driver* db);
+ ~QSQLite3Result();
+
+protected:
+ bool gotoNext(QSqlCachedResult::ValueCache& row, int idx);
+ bool reset (const QString& query);
+ int size();
+ int numRowsAffected();
+
+private:
+ QSQLite3ResultPrivate* d;
+};
+
+class QSQLite3Driver : public QSqlDriver
+{
+ friend class QSQLite3Result;
+public:
+ QSQLite3Driver(QObject *parent = 0, const char *name = 0);
+ QSQLite3Driver(sqlite3 *connection, QObject *parent = 0, const char *name = 0);
+ ~QSQLite3Driver();
+ bool hasFeature(DriverFeature f) const;
+ bool open(const QString & db,
+ const QString & user,
+ const QString & password,
+ const QString & host,
+ int port,
+ const QString & connOpts);
+ bool open( const QString & db,
+ const QString & user,
+ const QString & password,
+ const QString & host,
+ int port ) { return open (db, user, password, host, port, QString()); }
+ void close();
+ QSqlQuery createQuery() const;
+ bool beginTransaction();
+ bool commitTransaction();
+ bool rollbackTransaction();
+ QStringList tables(const QString &user) const;
+
+ QSqlRecord record(const QString& tablename) const;
+ QSqlRecordInfo recordInfo(const QString& tablename) const;
+ QSqlIndex primaryIndex(const QString &table) const;
+ QSqlRecord record(const QSqlQuery& query) const;
+ QSqlRecordInfo recordInfo(const QSqlQuery& query) const;
+
+private:
+ QSQLite3DriverPrivate* d;
+};
+#endif
diff --git a/src/svnqt/cache/sqlite3/qsqlcachedresult.cpp b/src/svnqt/cache/sqlite3/qsqlcachedresult.cpp
new file mode 100644
index 0000000..8a23183
--- /dev/null
+++ b/src/svnqt/cache/sqlite3/qsqlcachedresult.cpp
@@ -0,0 +1,260 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
+**
+** This file is part of the sql module of the Qt Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "qsqlcachedresult.h"
+
+#include <qvariant.h>
+#include <qdatetime.h>
+#include <qvaluevector.h>
+
+static const uint initial_cache_size = 128;
+
+class QSqlCachedResultPrivate
+{
+public:
+ QSqlCachedResultPrivate();
+ bool canSeek(int i) const;
+ inline int cacheCount() const;
+ void init(int count, bool fo);
+ void cleanup();
+ int nextIndex();
+ void revertLast();
+
+ QSqlCachedResult::ValueCache cache;
+ int rowCacheEnd;
+ int colCount;
+ bool forwardOnly;
+};
+
+QSqlCachedResultPrivate::QSqlCachedResultPrivate():
+ rowCacheEnd(0), colCount(0), forwardOnly(false)
+{
+}
+
+void QSqlCachedResultPrivate::cleanup()
+{
+ cache.clear();
+ forwardOnly = false;
+ colCount = 0;
+ rowCacheEnd = 0;
+}
+
+void QSqlCachedResultPrivate::init(int count, bool fo)
+{
+ Q_ASSERT(count);
+ cleanup();
+ forwardOnly = fo;
+ colCount = count;
+ if (fo) {
+ cache.resize(count);
+ rowCacheEnd = count;
+ } else {
+ cache.resize(initial_cache_size * count);
+ }
+}
+
+int QSqlCachedResultPrivate::nextIndex()
+{
+ if (forwardOnly)
+ return 0;
+ int newIdx = rowCacheEnd;
+ if (rowCacheEnd == (int)cache.size())
+ cache.resize(cache.size() * 2);
+/* if (newIdx + colCount > cache.size()){
+ if(cache.size() * 2 < cache.size() + 10000)
+ cache.resize(cache.size() * 2);
+ else
+ cache.resize(cache.size() + 10000);
+ }*/
+ rowCacheEnd += colCount;
+
+ return newIdx;
+}
+
+bool QSqlCachedResultPrivate::canSeek(int i) const
+{
+ if (forwardOnly || i < 0)
+ return false;
+ return rowCacheEnd >= (i + 1) * colCount;
+}
+
+void QSqlCachedResultPrivate::revertLast()
+{
+ if (forwardOnly)
+ return;
+ rowCacheEnd -= colCount;
+}
+
+inline int QSqlCachedResultPrivate::cacheCount() const
+{
+ Q_ASSERT(!forwardOnly);
+ Q_ASSERT(colCount);
+ return rowCacheEnd / colCount;
+}
+
+//////////////
+
+QSqlCachedResult::QSqlCachedResult(const QSqlDriver * db): QSqlResult (db)
+{
+ d = new QSqlCachedResultPrivate();
+}
+
+QSqlCachedResult::~QSqlCachedResult()
+{
+ delete d;
+}
+
+void QSqlCachedResult::init(int colCount)
+{
+ d->init(colCount, isForwardOnly());
+}
+
+bool QSqlCachedResult::fetch(int i)
+{
+ if ((!isActive()) || (i < 0))
+ return false;
+ if (at() == i)
+ return true;
+ if (d->forwardOnly) {
+ // speed hack - do not copy values if not needed
+ if (at() > i || at() == QSql::AfterLast)
+ return false;
+ while(at() < i - 1) {
+ if (!gotoNext(d->cache, -1))
+ return false;
+ setAt(at() + 1);
+ }
+ if (!gotoNext(d->cache, 0))
+ return false;
+ setAt(at() + 1);
+ return true;
+ }
+ if (d->canSeek(i)) {
+ setAt(i);
+ return true;
+ }
+ if (d->rowCacheEnd > 0)
+ setAt(d->cacheCount()-1);
+ while (at() < i) {
+ if (!cacheNext())
+ return false;
+ }
+ return true;
+}
+
+bool QSqlCachedResult::fetchNext()
+{
+ if (d->canSeek(at() + 1)) {
+ setAt(at() + 1);
+ return true;
+ }
+ return cacheNext();
+}
+
+bool QSqlCachedResult::fetchPrevious()
+{
+ return fetch(at() - 1);
+}
+
+bool QSqlCachedResult::fetchFirst()
+{
+ if (d->forwardOnly && at() != QSql::BeforeFirst) {
+ return false;
+ }
+ if (d->canSeek(0)) {
+ setAt(0);
+ return true;
+ }
+ return cacheNext();
+}
+
+bool QSqlCachedResult::fetchLast()
+{
+ if (at() == QSql::AfterLast) {
+ if (d->forwardOnly)
+ return false;
+ else
+ return fetch(d->cacheCount() - 1);
+ }
+
+ int i = at();
+ while (fetchNext())
+ ++i; /* brute force */
+ if (d->forwardOnly && at() == QSql::AfterLast) {
+ setAt(i);
+ return true;
+ } else {
+ return fetch(i);
+ }
+}
+
+QVariant QSqlCachedResult::data(int i)
+{
+ int idx = d->forwardOnly ? i : at() * d->colCount + i;
+ if (i >= d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
+ return QVariant();
+
+ return d->cache.at(idx);
+}
+
+bool QSqlCachedResult::isNull(int i)
+{
+ int idx = d->forwardOnly ? i : at() * d->colCount + i;
+ if (i > d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
+ return true;
+
+ return d->cache.at(idx).isNull();
+}
+
+void QSqlCachedResult::cleanup()
+{
+ setAt(QSql::BeforeFirst);
+ setActive(false);
+ d->cleanup();
+}
+
+bool QSqlCachedResult::cacheNext()
+{
+ if (!gotoNext(d->cache, d->nextIndex())) {
+ d->revertLast();
+ return false;
+ }
+ setAt(at() + 1);
+ return true;
+}
+
+int QSqlCachedResult::colCount() const
+{
+ return d->colCount;
+}
+
+QSqlCachedResult::ValueCache &QSqlCachedResult::cache()
+{
+ return d->cache;
+}
+
diff --git a/src/svnqt/cache/sqlite3/qsqlcachedresult.h b/src/svnqt/cache/sqlite3/qsqlcachedresult.h
new file mode 100644
index 0000000..fa8924f
--- /dev/null
+++ b/src/svnqt/cache/sqlite3/qsqlcachedresult.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
+**
+** This file is part of the sql module of the Qt Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef QSQLCACHEDRESULT_P_H
+#define QSQLCACHEDRESULT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qsqlresult.h>
+
+class QVariant;
+template <typename T> class QValueVector;
+
+class QSqlCachedResultPrivate;
+
+class QM_EXPORT_SQL QSqlCachedResult: public QSqlResult
+{
+public:
+ virtual ~QSqlCachedResult();
+
+ typedef QValueVector<QVariant> ValueCache;
+
+protected:
+ QSqlCachedResult(const QSqlDriver * db);
+
+ void init(int colCount);
+ void cleanup();
+
+ virtual bool gotoNext(ValueCache &values, int index) = 0;
+
+ QVariant data(int i);
+ bool isNull(int i);
+ bool fetch(int i);
+ bool fetchNext();
+ bool fetchPrevious();
+ bool fetchFirst();
+ bool fetchLast();
+
+ int colCount() const;
+ ValueCache &cache();
+
+private:
+ bool cacheNext();
+ QSqlCachedResultPrivate *d;
+};
+
+#endif // QSQLCACHEDRESULT_P_H
diff --git a/src/svnqt/cache/test/CMakeLists.txt b/src/svnqt/cache/test/CMakeLists.txt
new file mode 100644
index 0000000..ecc6130
--- /dev/null
+++ b/src/svnqt/cache/test/CMakeLists.txt
@@ -0,0 +1,19 @@
+SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
+
+MACRO(BUILD_TEST tname)
+ SET(${tname}-src ${tname}.cpp)
+ IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${tname}.h)
+ SET(${tname}-src ${${tname}-src} ${tname}.h)
+ ENDIF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${tname}.h)
+ ADD_EXECUTABLE(${tname} ${${tname}-src})
+ TARGET_LINK_LIBRARIES(${tname} ${svnqt-name} ${QT_LIBRARIES})
+ ADD_TEST(${tname} ${CMAKE_CURRENT_BINARY_DIR}/${tname})
+ENDMACRO(BUILD_TEST)
+
+IF (BUILD_TESTS)
+ CONFIGURE_FILE(
+ ${CMAKE_CURRENT_SOURCE_DIR}/testconfig.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/testconfig.h
+ )
+ BUILD_TEST(sqlite)
+ENDIF(BUILD_TESTS)
diff --git a/src/svnqt/cache/test/sqlite.cpp b/src/svnqt/cache/test/sqlite.cpp
new file mode 100644
index 0000000..4f14b2d
--- /dev/null
+++ b/src/svnqt/cache/test/sqlite.cpp
@@ -0,0 +1,111 @@
+#include <qsql.h>
+#include <qsqldatabase.h>
+#include <qstringlist.h>
+#include <iostream>
+#include <qapplication.h>
+#include <qtextstream.h>
+
+#include "svnqt/client.hpp"
+#include "svnqt/svnqttypes.hpp"
+#include "svnqt/log_entry.hpp"
+
+#include "svnqt/cache/LogCache.hpp"
+#include "svnqt/cache/ReposLog.hpp"
+#include "svnqt/cache/test/testconfig.h"
+#include "svnqt/cache/DatabaseException.hpp"
+
+#if QT_VERSION < 0x040000
+#else
+#include <QSqlQuery>
+#include <QSqlError>
+#endif
+
+int main(int argc,char**argv)
+{
+ QApplication app(argc,argv);
+
+ svn::ContextP m_CurrentContext;
+ svn::Client* m_Svnclient;
+ m_Svnclient=svn::Client::getobject(0,0);
+ m_CurrentContext = new svn::Context();
+
+ m_Svnclient->setContext(m_CurrentContext);
+
+ QStringList list;
+ QStringList::Iterator it;
+ // goes into "self" of logcache
+ new svn::cache::LogCache(TESTDBPATH);
+ list = QSqlDatabase::drivers();
+ it = list.begin();
+ while( it != list.end() ) {
+ std::cout << (*it).TOUTF8().data() << std::endl;
+ ++it;
+ }
+ svn::cache::ReposLog rl(m_Svnclient,"http://www.alwins-world.de/repos/kdesvn");
+ QDataBase db = rl.Database();
+#if QT_VERSION < 0x040000
+ if (!db) {
+#else
+ if (!db.isValid()) {
+#endif
+ std::cerr << "No database object."<<std::endl;
+ exit(-1);
+ }
+#if QT_VERSION < 0x040000
+ list = db->tables();
+#else
+ list = db.tables();
+#endif
+ it = list.begin();
+ while( it != list.end() ) {
+ std::cout << ( *it ).TOUTF8().data() << std::endl;
+ ++it;
+ }
+ svn::LogEntriesMap lm;
+ try {
+ rl.simpleLog(lm,100,svn::Revision::HEAD);
+ }
+ catch (const svn::cache::DatabaseException&cl)
+ {
+ std::cerr << cl.msg().TOUTF8().data() <<std::endl;
+ }
+ catch (const svn::Exception&ce)
+ {
+ std::cerr << "Exception: " << ce.msg().TOUTF8().data() <<std::endl;
+ }
+ svn::LogEntriesMap::ConstIterator lit = lm.begin();
+ std::cout<<"Count: "<<lm.count()<<std::endl;
+
+ svn::Revision r("{2006-09-27}");
+ std::cout << r.toString().TOUTF8().data() << " -> " << rl.date2numberRev(r).toString().TOUTF8().data()<<std::endl;
+ r = svn::Revision::HEAD;
+ std::cout << rl.date2numberRev(r).toString().TOUTF8().data()<<std::endl;
+ try {
+ rl.insertLogEntry(lm[100]);
+ }
+ catch (const svn::cache::DatabaseException&cl)
+ {
+ std::cerr << cl.msg().TOUTF8().data() << std::endl;
+ }
+ QSqlQuery q("insert into logentries(revision,date,author,message) values ('100','1122591406','alwin','copy and moving works now in basic form')",db);
+ q.exec();
+ std::cerr << "\n" << q.lastError().text().TOUTF8().data()<<std::endl;
+
+#if QT_VERSION < 0x040000
+#else
+ db=QSqlDatabase();
+#endif
+ try {
+ rl.log("/trunk/src/svnqt",1,1000,svn::Revision::UNDEFINED,lm,false,-1);
+ }
+ catch (const svn::cache::DatabaseException&cl)
+ {
+ std::cerr << cl.msg().TOUTF8().data() <<std::endl;
+ }
+ catch (const svn::Exception&ce)
+ {
+ std::cerr << "Exception: " << ce.msg().TOUTF8().data() <<std::endl;
+ }
+ std::cout<<"Count: "<<lm.count()<<std::endl;
+ return 0;
+}
diff --git a/src/svnqt/cache/test/testconfig.h.in b/src/svnqt/cache/test/testconfig.h.in
new file mode 100644
index 0000000..865ac6e
--- /dev/null
+++ b/src/svnqt/cache/test/testconfig.h.in
@@ -0,0 +1,8 @@
+#ifndef __TEST_CONFIG_H
+#define __TEST_CONFIG_H
+
+#define TESTREPOPATH "@CMAKE_CURRENT_BINARY_DIR@/repo"
+#define TESTCOPATH "@CMAKE_CURRENT_BINARY_DIR@/co"
+#define TESTDBPATH "@CMAKE_CURRENT_BINARY_DIR@/db"
+
+#endif
diff --git a/src/svnqt/check.hpp b/src/svnqt/check.hpp
new file mode 100644
index 0000000..0c6a340
--- /dev/null
+++ b/src/svnqt/check.hpp
@@ -0,0 +1,50 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_CHECK_HPP_
+#define _SVNCPP_CHECK_HPP_
+
+// subversion api
+#include "svn_version.h"
+
+/**
+ * Check if the current version of the subversion
+ * API is at least major.minor
+ */
+#define CHECK_SVN_VERSION (major,minor) \
+ (SVN_VER_MAJOR > (major) || \
+ (SVN_VER_MAJOR == (major) && SVN_VER_MINOR > (minor))
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client.cpp b/src/svnqt/client.cpp
new file mode 100644
index 0000000..d78c416
--- /dev/null
+++ b/src/svnqt/client.cpp
@@ -0,0 +1,104 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1550
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+
+// svncpp
+#include "svnqt/client.hpp"
+#include "svnqt/client_impl.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include "svn_opt.h"
+
+#include <svn_cmdline.h>
+
+#include <qstringlist.h>
+#include <qdir.h>
+
+namespace svn
+{
+ //! this namespace contains only internal stuff not for public use
+ namespace internal {
+ //! small helper class
+ /*!
+ There will be an static instance created for calling the constructor at program load.
+ */
+ class SvnInit
+ {
+ public:
+ //! constructor calling initialize functions
+ SvnInit();
+ ~SvnInit(){};
+ };
+
+ SvnInit::SvnInit() {
+ svn_cmdline_init("svnqt",0);
+ qDebug("svn_cmdline_init done");
+ QString BasePath=QDir::HOMEDIR();
+ QDir d;
+ if (!d.exists(BasePath)) {
+ d.mkdir(BasePath);
+ }
+ BasePath=BasePath+"/"+".svnqt";
+ if (!d.exists(BasePath)) {
+ d.mkdir(BasePath);
+ }
+
+ }
+ }
+
+ Client::Client()
+ {
+ }
+
+ Client::~Client ()
+ {
+ }
+
+ Client*Client::getobject(ContextP context,int subtype)
+ {
+ static internal::SvnInit sInit;
+ switch(subtype) {
+ case 0:
+ return new Client_impl(context);
+ break;
+ default:
+ break;
+ }
+ return 0L;
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client.hpp b/src/svnqt/client.hpp
new file mode 100644
index 0000000..622c0be
--- /dev/null
+++ b/src/svnqt/client.hpp
@@ -0,0 +1,882 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_CLIENT_H_
+#define _SVNCPP_CLIENT_H_
+
+// Ignore MSVC 6 compiler warning: debug symbol truncated
+#if defined (_MSC_VER) && _MSC_VER <= 1200
+#pragma warning (disable: 4786)
+#endif
+
+// Ignore MSVC 7, 2005 & 2008 compiler warning: C++ exception specification
+#if defined (_MSC_VER) && _MSC_VER > 1200 && _MSC_VER <= 1550
+#pragma warning (disable: 4290)
+#endif
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/svnqttypes.hpp"
+#include "svnqt/svnstream.hpp"
+
+// qt
+#include <qglobal.h>
+
+#if QT_VERSION < 0x040000
+ #include <qstring.h>
+ #include <qpair.h>
+ #include <qvaluelist.h>
+ #include <qmap.h>
+#else
+ #include <QtCore>
+#endif
+
+// svnqt
+#include "svnqt/context.hpp"
+#include "svnqt/exception.hpp"
+#include "svnqt/path.hpp"
+#include "svnqt/entry.hpp"
+#include "svnqt/revision.hpp"
+#include "svnqt/log_entry.hpp"
+#include "svnqt/info_entry.hpp"
+#include "svnqt/annotate_line.hpp"
+#include "svnqt/stringarray.hpp"
+#include "svnqt/diffoptions.hpp"
+#include "svnqt/conflictresult.hpp"
+
+class QStringList;
+
+namespace svn
+{
+ /** Subversion client API.
+ *
+ * Never use an object of this as global static! This will make problems with subversion
+ * initialize.
+ */
+ class SVNQT_EXPORT Client
+ {
+ public:
+
+ /**
+ * Initializes the primary memory pool.
+ */
+ Client();
+
+ virtual ~Client ();
+
+
+ /**
+ * @return returns the Client context
+ */
+ virtual const ContextP
+ getContext () const = 0;
+
+ /**
+ * sets the client context
+ * you have to make sure the old context
+ * is de-allocated
+ *
+ * @param context new context to use
+ */
+ virtual void
+ setContext (ContextP context) = 0;
+
+ /**
+ * get a real instance. Result must cleaned with delete.
+ * \param context The context to use
+ * \param subtype the wanted implementation - this moment only 0 allowed.
+ * \return an instance of client or 0L if error.
+ */
+ static Client*getobject(ContextP context,int subtype=0);
+
+ /**
+ * Enumerates all files/dirs at a given path.
+ *
+ * Throws an exception if an error occurs
+ *
+ * @param path Path to explore.
+ * @param descend Recurse into subdirectories if existant.
+ * @param get_all Return all entries, not just the interesting ones.
+ * @param update Query the repository for updates.
+ * @param no_ignore Disregard default and svn:ignore property ignores.
+ * @param hide_externals don't recurse into external definitions
+ * @param revision list specific revision when browsing remote, on working copies parameter will ignored
+ * @param detailed_remote if on remote listing detailed item info should get if possible
+ * that may slow so should configureable in frontends!
+ * @return vector with Status entries.
+ */
+ virtual StatusEntries
+ status (const Path& path,
+ Depth depth=DepthImmediates,
+ bool get_all = true,
+ bool update = false,
+ bool no_ignore = false,
+ const Revision revision = svn::Revision::HEAD,
+ bool detailed_remote = false,
+ bool hide_externals = false,
+ const StringArray & changelists=StringArray() ) throw (ClientException) = 0;
+
+ /**
+ * Returns the status of a single file in the path.
+ *
+ * Throws an exception if an error occurs
+ *
+ * @param path File to gather status.
+ * @param update if check against repository if new updates are there (for WC only)
+ * @param revision list specific revision when browsing remote, on working copies parameter will ignored
+ * @return a Status with Statis.isVersioned = FALSE
+ */
+ virtual StatusPtr
+ singleStatus (const Path& path,bool update=false,const Revision revision = svn::Revision::HEAD) throw (ClientException)=0;
+
+ /**
+ * Executes a revision checkout.
+ * @param moduleName name of the module to checkout.
+ * @param destPath destination directory for checkout.
+ * @param revision the revision number to checkout. If the number is -1
+ * then it will checkout the latest revision.
+ * @param peg Revision to look up
+ * @param recurse whether you want it to checkout files recursively.
+ * @param ignore_externals if true don't process externals definitions.
+ * @exception ClientException
+ */
+ virtual svn_revnum_t
+ checkout (const Path& moduleName, const Path & destPath,
+ const Revision & revision,
+ const Revision & peg = Revision::UNDEFINED,
+ svn::Depth depth=DepthInfinity,
+ bool ignore_externals=false,
+ bool overwrite=false
+ ) throw (ClientException) = 0;
+
+ /**
+ * relocate wc @a from to @a to
+ * @exception ClientException
+ */
+ virtual void
+ relocate (const Path & path, const QString &from_url,
+ const QString &to_url, bool recurse) throw (ClientException)=0;
+
+ /**
+ * Sets a single file for deletion.
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ remove (const Path & path, bool force,
+ bool keep_local = true,
+ const PropertiesMap&revProps = PropertiesMap()) throw (ClientException)=0;
+
+ /**
+ * Sets files for deletion.
+ *
+ * @param targets targets to delete
+ * @param force force if files are locally modified
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ remove (const Targets & targets,
+ bool force,
+ bool keep_local=true,
+ const PropertiesMap&revProps=PropertiesMap()) throw (ClientException) = 0;
+
+ /**
+ * Reverts a couple of files to a pristiner state.
+ * @exception ClientException
+ */
+ virtual void
+ revert (const Targets & targets,
+ Depth depth,
+ const StringArray&changelist=StringArray()
+ ) throw (ClientException)=0;
+
+
+ /**
+ * Adds a file to the repository.
+ * @param path the path to add
+ * @param depth if @a path is a folder add items recursive depending on value if it.
+ * @param force if true, do not error on already-versioned items.
+ * @param no_ignore if false don't add files or directories that match ignore patterns. When build against svn 1.2 always false
+ * @param add_parents if true, go up to the next versioned folder and add all between path and this folder.
+ * @exception ClientException
+ */
+ virtual void
+ add (const Path & path, svn::Depth depth,bool force=false, bool no_ignore=false, bool add_parents = true) throw (ClientException)=0;
+
+ /**
+ * Updates the file or directory.
+ * @param path targets.
+ * @param revision the revision number to checkout.
+ * Revision::HEAD will checkout the
+ * latest revision.
+ * @param depth Depthness for operation
+ * @param ignore_externals ignore externals
+ * @param allow_unversioned will operation not fail if there are unversioned items in tree with same name.
+ * @exception ClientException
+ */
+ virtual Revisions
+ update (const Targets & path, const Revision & revision,
+ Depth depth,bool ignore_externals,bool allow_unversioned,
+ bool sticky_depth) throw (ClientException) = 0;
+
+ /**
+ * Retrieves the contents for a specific @a revision of
+ * a @a path at @a peg_revision
+ *
+ * @param path path of file or directory
+ * @param peg_revision revision to base the URL
+ * @param revision revision to retrieve
+ * @return contents of the file
+ */
+ virtual QByteArray
+ cat (const Path & path,
+ const Revision & revision,
+ const Revision & peg_revision=svn_opt_revision_unspecified) throw (ClientException)=0;
+ /**
+ * Retrieves the contents for a specific @a revision of
+ * a @a path at @a peg_revision
+ *
+ * @param buffer Stream to store content direct
+ * @param path path of file or directory
+ * @param peg_revision revision to base the URL
+ * @param revision revision to retrieve
+ * @exception ClientException
+ */
+ virtual void
+ cat(svn::stream::SvnStream&buffer,
+ const Path & path,
+ const Revision & revision,
+ const Revision & peg_revision) throw (ClientException)=0;
+ /**
+ * Retrieves the contents for a specific @a revision of
+ * a @a path at @a peg_revision
+ *
+ * @param path path of file or directory
+ * @param target new (local) name
+ * @param peg_revision revision to base the URL
+ * @param revision revision to retrieve
+ * @param peg_revision Revision to look at
+ */
+ virtual void
+ get (const Path & path,
+ const QString & target,
+ const Revision & revision,
+ const Revision & peg_revision=svn_opt_revision_unspecified) throw (ClientException)=0;
+
+ /**
+ * Retrieves the contents for a specific @a revision of
+ * a @a path and stores the result in @a target
+ *
+ * @param target the container where to store the result
+ * @param path path of file or directory
+ * @param revisionStart revision to retrieve
+ * @param revisionEnd revision to retrieve
+ * @param peg indicates in which revision path is valid
+ */
+ virtual void
+ annotate (AnnotatedFile&target,
+ const Path & path,
+ const Revision & revisionStart,
+ const Revision & revisionEnd,
+ const Revision & peg = Revision::UNDEFINED,
+ const DiffOptions&diffoptions = DiffOptions(),
+ bool ignore_mimetypes = false,
+ bool include_merged_revisions = false
+ ) throw (ClientException)=0;
+
+ /**
+ * Commits changes to the repository. This usually requires
+ * authentication, see Auth.
+ * @return Returns revision transferred or svn::Revision::UNDEFINED if the revision number is invalid.
+ * @param targets files to commit.
+ * @param message log message.
+ * @param depth whether the operation should be done recursively.
+ * @param keep_locks if false unlock items in paths
+ * @param changelist
+ * @param keep_changelist
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ commit (const Targets & targets,
+ const QString& message,
+ svn::Depth depth,bool keep_locks=true,
+ const svn::StringArray&contents=svn::StringArray(),
+ const PropertiesMap&revProps=PropertiesMap(),
+ bool keep_changelist=false
+ ) throw (ClientException)=0;
+
+ /**
+ * Copies a versioned file with the history preserved.
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ copy (const Path & srcPath,
+ const Revision & srcRevision,
+ const Path & destPath) throw (ClientException)=0;
+ /**
+ * Copies a versioned file with the history preserved.
+ * @since subversion 1.5 api
+ * @see svn_client_copy4
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ copy (const Targets & srcPath,
+ const Revision & srcRevision,
+ const Revision & pegRevision,
+ const Path & destPath,
+ bool asChild=false,bool makeParent=false,const PropertiesMap&revProps=PropertiesMap()) throw (ClientException)=0;
+
+ /**
+ * Moves or renames a file.
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ move (const Path & srcPath,
+ const Path & destPath,
+ bool force) throw (ClientException)=0;
+ /**
+ * Moves or renames a file.
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ move (const Targets & srcPath,
+ const Path & destPath,
+ bool force,bool asChild,bool makeParent,const PropertiesMap&revProps=PropertiesMap()) throw (ClientException)=0;
+
+ /**
+ * Creates a directory directly in a repository or creates a
+ * directory on disk and schedules it for addition. If <i>path</i>
+ * is a URL then authentication is usually required, see Auth and
+ * the callback asks for a logmessage. With subversion 1.4 the target
+ * must not exist (\sa svn_client_move4)
+ *
+ * @param path
+ * @param message log message. if it is QString::null asks when working on repository
+ * @param makeParent create parent folders if not existant (only when build with svn 1.5 or above)
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ mkdir (const Path & path,
+ const QString& message,
+ bool makeParent=true,
+ const PropertiesMap&revProps=PropertiesMap()
+ ) throw (ClientException)=0;
+ /**
+ * Creates a directory directly in a repository or creates a
+ * directory on disk and schedules it for addition. If <i>path</i>
+ * is a URL then authentication is usually required, see Auth and
+ * the callback asks for a logmessage.
+ *
+ * @param targets encoded pathes to create
+ * @param message log message. if it is QString::null asks when working on repository
+ * @param makeParent create parent folders if not existant (only when build with svn 1.5 or above)
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ mkdir (const Targets & targets,
+ const QString& message,
+ bool makeParent=true,
+ const PropertiesMap&revProps=PropertiesMap()
+ ) throw (ClientException)=0;
+
+ /**
+ * Recursively cleans up a local directory, finishing any
+ * incomplete operations, removing lockfiles, etc.
+ * @param path a local directory.
+ * @exception ClientException
+ */
+ virtual void
+ cleanup (const Path & path) throw (ClientException)=0;
+
+ /**
+ * Removes the 'conflicted' state on a file.
+ * @exception ClientException
+ */
+ virtual void resolve (const Path & path,Depth depth,const ConflictResult&resolution=ConflictResult()) throw (ClientException)=0;
+
+ /**
+ * Exports the contents of either a subversion repository into a
+ * 'clean' directory (meaning a directory with no administrative
+ * directories).
+ * @exception ClientException
+ * @param srcPath source path
+ * @param destPath a destination path that must not already exist.
+ * @param revision revision to use for the export
+ * @param peg the revision where the path is first looked up when exporting from a repository.
+ * @param overwrite overwrite existing files
+ * @param native_eol Either "LF", "CR" or "CRLF" or NULL.
+ * @param ignore_externals don't process externals definitions as part of this operation.
+ * @param recurse if true, export recursively.<br>
+ Otherwise, export just the directory represented by from and its immediate non-directory children.
+ */
+ virtual svn_revnum_t
+ doExport (const Path & srcPath,
+ const Path & destPath,
+ const Revision & revision,
+ const Revision & peg = Revision::UNDEFINED,
+ bool overwrite=false,
+ const QString&native_eol=QString::null,
+ bool ignore_externals = false,
+ svn::Depth depth=svn::DepthInfinity
+ ) throw (ClientException)=0;
+
+ /**
+ * Update local copy to mirror a new url. This excapsulates the
+ * svn_client_switch() client method.
+ * @exception ClientException
+ */
+ virtual svn_revnum_t
+ doSwitch (
+ const Path & path, const QString& url,
+ const Revision & revision,
+ Depth depth,
+ const Revision & peg=Revision::UNDEFINED,
+ bool sticky_depth = true,
+ bool ignore_externals=false,
+ bool allow_unversioned=false
+ ) throw (ClientException)=0;
+
+ /**
+ * Import file or directory PATH into repository directory URL at
+ * head. This usually requires authentication, see Auth.
+ * @param path path to import
+ * @param url
+ * @param message log message.
+ * @param depth kind of recurse operation
+ * @param no_ignore if false, don't add items matching global ignore pattern (@since subversion 1.3)
+ * @param no_unknown_nodetype if true ignore files type not known like pipes or device files (@since subversion 1.5)
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ import (const Path & path, const QString& url,
+ const QString& message,
+ svn::Depth depth,
+ bool no_ignore,bool no_unknown_nodetype,
+ const PropertiesMap&revProps=PropertiesMap()) throw (ClientException)=0;
+
+ /**
+ * Merge changes from two paths into a new local path.
+ * @exception ClientException
+ */
+ virtual void
+ merge (const Path & path1, const Revision & revision1,
+ const Path & path2, const Revision & revision2,
+ const Path & localPath, bool force,
+ Depth depth,
+ bool notice_ancestry=false,
+ bool dry_run=false,
+ bool record_only=false,
+ const StringArray&merge_options=StringArray()
+ ) throw (ClientException)=0;
+
+ virtual void
+ merge_peg(const Path&src,
+ const RevisionRanges&ranges,
+ const Revision&peg,
+ const Path&targetWc,
+ Depth depth,
+ bool notice_ancestry=false,
+ bool dry_run=false,
+ bool force=false,
+ bool record_only=false,
+ const StringArray&merge_options=StringArray()
+ ) throw (ClientException)=0;
+
+ virtual void
+ merge_peg(const Path&src,
+ const RevisionRange&range,
+ const Revision&peg,
+ const Path&targetWc,
+ Depth depth,
+ bool notice_ancestry=false,
+ bool dry_run=false,
+ bool force=false,
+ const StringArray&merge_options=StringArray()
+ ) throw (ClientException)=0;
+
+ /**
+ * Retrieve information for the given path
+ * remote or local.
+ *
+ * @param path path for info
+ * @param rec recursive (if dir)
+ * @param rev for which revision
+ * @param peg_revision peg revision
+ * @return InfoEntries
+ */
+ virtual InfoEntries
+ info (const Path &path,
+ Depth depth,
+ const Revision & rev,
+ const Revision & peg_revision=svn_opt_revision_unspecified,
+ const StringArray&changelists=StringArray()
+ ) throw (ClientException)=0;
+
+ /**
+ * Retrieve log information for the given path
+ * Loads the log messages result set. The first
+ * entry is the youngest revision.
+ *
+ * You can use the constants Revision::START and
+ * Revision::HEAD
+ *
+ * @param path
+ * @param revisionStart
+ * @param revisionEnd
+ * @param discoverChangedPaths
+ * @param strictNodeHistory
+ * @param limit the maximum log entries count.
+ * @return a vector with log entries
+ */
+ virtual LogEntriesPtr
+ log (const Path& path,
+ const Revision & revisionStart,
+ const Revision & revisionEnd,
+ const Revision & revisionPeg,
+ bool discoverChangedPaths=false,
+ bool strictNodeHistory=true,int limit = 0,
+ bool include_merged_revisions = false,
+ const StringArray&revprops=StringArray()
+ ) throw (ClientException)=0;
+
+ /**
+ * Retrieve log information for the given path
+ * Loads the log messages result set. Result will stored
+ * in a map where the key is the revision number
+ *
+ * You can use the constants Revision::START and
+ * Revision::HEAD
+ *
+ * @param path Path to make a log for
+ * @param revisionStart
+ * @param revisionEnd
+ * @param target the logmap where to store the entries
+ * @param discoverChangedPaths
+ * @param strictNodeHistory
+ * @param limit (ignored when subversion 1.1 API)
+ * @return true if success
+ */
+ virtual bool
+ log (const Path& path, const Revision & revisionStart,
+ const Revision & revisionEnd,
+ LogEntriesMap&target,
+ const Revision & revisionPeg=Revision::UNDEFINED,
+ bool discoverChangedPaths=false,
+ bool strictNodeHistory=true,int limit = 0,
+ bool include_merged_revisions = false,
+ const StringArray&revprops=StringArray()
+ ) throw (ClientException)=0;
+
+ /**
+ * Produce diff output which describes the delta between
+ * @a path/@a revision1 and @a path/@a revision2. @a path
+ * can be either a working-copy path or a URL.
+ *
+ * A ClientException will be thrown if either @a revision1 or
+ * @a revision2 has an `unspecified' or unrecognized `kind'.
+ *
+ * @param tmpPath prefix for a temporary directory needed by diff.
+ * Filenames will have ".tmp" and similar added to this prefix in
+ * order to ensure uniqueness.
+ * @param path path of the file.
+ * @param revision1 one of the revisions to check.
+ * @param revision2 the other revision.
+ * @param recurse whether the operation should be done recursively.
+ * @param ignoreAncestry whether the files will be checked for
+ * relatedness.
+ * @param noDiffDeleted if true, no diff output will be generated on deleted files.
+ * @param ignore_contenttype if true generate diff even the items are marked as binaries
+ * @param extra extra options for diff ("-b", "-w","--ignore-eol-style")
+ * @return delta between the files
+ * @exception ClientException
+ */
+ virtual QByteArray
+ diff_peg(const Path & tmpPath, const Path & path,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2, const Revision& peg_revision,
+ Depth depth, bool ignoreAncestry,
+ bool noDiffDeleted,bool ignore_contenttype,
+ const StringArray&extra,
+ const StringArray&changelists
+ ) throw (ClientException)=0;
+
+ /**
+ * Same as other diff but extra options always set to empty list.
+ */
+ virtual QByteArray
+ diff_peg (const Path & tmpPath, const Path & path,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2, const Revision& peg_revision,
+ Depth depth, bool ignoreAncestry,
+ bool noDiffDeleted,bool ignore_contenttype) throw (ClientException)=0;
+
+ /**
+ * Produce diff output which describes the delta between
+ * @a path1/@a revision1 and @a path2/@a revision2. @a path2
+ * can be either a working-copy path or a URL.
+ *
+ * A ClientException will be thrown if either @a revision1 or
+ * @a revision2 has an `unspecified' or unrecognized `kind'.
+ *
+ * @param tmpPath prefix for a temporary directory needed by diff.
+ * Filenames will have ".tmp" and similar added to this prefix in
+ * order to ensure uniqueness.
+ * @param path1 first file or folder to diff.
+ * @param path2 second file or folder to diff.
+ * @param revision1 one of the revisions to check (path1).
+ * @param revision2 the other revision (path2).
+ * @param recurse whether the operation should be done recursively.
+ * @param ignoreAncestry whether the files will be checked for
+ * relatedness.
+ * @param noDiffDeleted if true, no diff output will be generated on deleted files.
+ * @param ignore_contenttype if true generate diff even the items are marked as binaries
+ * @param extra extra options for diff ("-b", "-w","--ignore-eol-style")
+ * @return delta between the files
+ * @exception ClientException
+ */
+ virtual QByteArray
+ diff (const Path & tmpPath, const Path & path1,const Path & path2,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2,
+ Depth depth, bool ignoreAncestry,
+ bool noDiffDeleted,bool ignore_contenttype,
+ const StringArray&extra,
+ const StringArray&changelists
+ ) throw (ClientException)=0;
+
+ /**
+ * Same as other diff but extra options and changelists always set to empty list.
+ */
+ virtual QByteArray
+ diff (const Path & tmpPath, const Path & path1,const Path & path2,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2,
+ Depth depth, bool ignoreAncestry,
+ bool noDiffDeleted,bool ignore_contenttype) throw (ClientException)=0;
+
+ /**
+ * lists entries in @a pathOrUrl no matter whether local or
+ * repository
+ *
+ * If checking for locks is activated, it lists the locks inside repository, not locks inside
+ * working copy!
+ * @param pathOrUrl
+ * @param revision
+ * @param peg at wich revision path exists
+ * @param depth @sa depth
+ * @param retrieve_locks check for REPOSITORY locks while listing.
+ * @return a vector of directory entries, each with
+ * a relative path (only filename). In subversion >= 1.4 an entry without a name is returned, too. This
+ * is the searched directory (done in subversion itself)
+ */
+ virtual DirEntries
+ list (const Path& pathOrUrl,
+ const Revision& revision,
+ const Revision& peg,
+ svn::Depth depth,bool retrieve_locks) throw (ClientException)=0;
+
+ /**
+ * lists properties in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param revision
+ * @param peg most case should set to @a revision
+ * @param recurse
+ * @return PropertiesList
+ */
+ virtual PathPropertiesMapListPtr
+ proplist(const Path &path,
+ const Revision &revision,
+ const Revision &peg,
+ Depth depth=DepthEmpty,
+ const StringArray&changelists=StringArray()
+ )=0;
+
+ /**
+ * lists one property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param path
+ * @param revision
+ * @param peg most case should set to @a revision
+ * @param recurse
+ * @return PathPropertiesMapList and revision where the properties are taken from (svn 1.5) or undefined revision (prior 1.5)
+ */
+ virtual QPair<QLONG,PathPropertiesMapList>
+ propget(const QString& propName,
+ const Path &path,
+ const Revision &revision,
+ const Revision &peg,
+ Depth depth = svn::DepthEmpty,
+ const StringArray&changelists=StringArray()) = 0;
+
+ /**
+ * set property in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param revision
+ * @param propName
+ * @param propValue
+ * @param recurse
+ * @param skip_checks if true skip validity checks
+ * @return PropertiesList
+ */
+ virtual void
+ propset(const QString& propName,
+ const QString& propValue,
+ const Path &path,
+ Depth depth=DepthEmpty,
+ bool skip_checks=false,
+ const Revision&base_revision=Revision::UNDEFINED,
+ const StringArray&changelists=StringArray(),
+ const PropertiesMap&revProps=PropertiesMap()
+ ) = 0;
+
+ /**
+ * delete property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param path
+ * @param revision
+ * @param recurse
+ */
+ virtual void
+ propdel(const QString& propName,
+ const Path &path,
+ Depth depth=DepthEmpty,
+ bool skip_check=false,
+ const Revision&base_revision=Revision::UNDEFINED,
+ const StringArray&changelists=StringArray())=0;
+
+
+ /**
+ * lists revision properties in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param revision
+ * @return PropertiesList
+ */
+ virtual QPair<QLONG,PropertiesMap>
+ revproplist(const Path &path,
+ const Revision &revision)=0;
+
+ /**
+ * lists one revision property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param path
+ * @param revision
+ * @return PropertiesList
+ */
+ virtual QPair<QLONG,QString>
+ revpropget(const QString& propName,
+ const Path &path,
+ const Revision &revision)=0;
+
+ /**
+ * set revision property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param propValue
+ * @param path
+ * @param revision
+ * @param force
+ * @return Revision
+ */
+ virtual QLONG
+ revpropset(const QString& propName,
+ const QString& propValue,
+ const Path &path,
+ const Revision &revision,
+ bool force=false)=0;
+
+ /**
+ * delete revision property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param path
+ * @param revision
+ * @param force
+ * @return Revision
+ */
+ virtual QLONG
+ revpropdel(const QString& propName,
+ const Path &path,
+ const Revision &revision,
+ bool force=false) = 0;
+
+ /**
+ * lock files in repository or working copy
+ * @param targets items to be locked
+ * @param message if non null stored with each lock in repository
+ * @param steal_lock if true locks in wc will stolen.
+ * @since subversion 1.2
+ */
+ virtual void
+ lock (const Targets & targets,
+ const QString& message,
+ bool steal_lock) throw (ClientException)=0;
+ /**
+ * unlock files in repository or working copy
+ * @param targets items to unlock
+ * @param break_lock ignore any errors
+ */
+ virtual void
+ unlock (const Targets&targets,
+ bool break_lock) throw (ClientException)=0;
+
+ virtual void
+ url2Revision(const QString&revstring,
+ Revision&start,Revision&end)=0;
+ virtual void
+ url2Revision(const QString&revstring,
+ Revision&start)=0;
+
+ private:
+ /**
+ * disallow assignment operator
+ */
+ Client & operator= (const Client &);
+ /**
+ * disallow copy constructor
+ */
+ Client (const Client &);
+ };
+
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client_annotate.cpp b/src/svnqt/client_annotate.cpp
new file mode 100644
index 0000000..96bc92c
--- /dev/null
+++ b/src/svnqt/client_annotate.cpp
@@ -0,0 +1,142 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1200
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+// svncpp
+#include "svnqt/client_impl.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+// Subversion api
+#include "svn_client.h"
+
+
+
+namespace svn
+{
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ static svn_error_t *
+ annotateReceiver(void *baton,
+ apr_int64_t line_no,
+ svn_revnum_t revision,
+ const char *author,
+ const char *date,
+ svn_revnum_t merge_revision,
+ const char *merge_author,
+ const char *merge_date,
+ const char *merge_path,
+ const char *line,
+ apr_pool_t *)
+ {
+ AnnotatedFile * entries = (AnnotatedFile *) baton;
+ entries->push_back (AnnotateLine(line_no, revision,author,
+ date,line,merge_revision,
+ merge_author,merge_date,merge_path));
+ return NULL;
+ }
+#else
+ static svn_error_t *
+ annotateReceiver(void *baton,
+ apr_int64_t line_no,
+ svn_revnum_t revision,
+ const char *author,
+ const char *date,
+ const char *line,
+ apr_pool_t *)
+ {
+ AnnotatedFile * entries = (AnnotatedFile *) baton;
+ entries->push_back (
+ AnnotateLine (line_no, revision,
+ author?author:"",
+ date?date:"",
+ line?line:""));
+
+ return NULL;
+ }
+#endif
+
+ void
+ Client_impl::annotate (AnnotatedFile&target,const Path & path,
+ const Revision & revisionStart,
+ const Revision & revisionEnd,
+ const Revision & peg,
+ const DiffOptions&diffoptions,
+ bool ignore_mimetypes,
+ bool include_merged_revisions
+ ) throw (ClientException)
+ {
+ Pool pool;
+ svn_error_t *error;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_blame4(
+ path.path().TOUTF8(),
+ peg.revision(),
+ revisionStart.revision (),
+ revisionEnd.revision (),
+ diffoptions.options(pool),
+ ignore_mimetypes,
+ include_merged_revisions,
+ annotateReceiver,
+ &target,
+ *m_context, // client ctx
+ pool);
+#elif ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ Q_UNUSED(include_merged_revisions);
+ error = svn_client_blame3(
+ path.path().TOUTF8(),
+ peg.revision(),
+ revisionStart.revision (),
+ revisionEnd.revision (),
+ diffoptions.options(pool),
+ ignore_mimetypes,
+ annotateReceiver,
+ &target,
+ *m_context, // client ctx
+ pool);
+#else
+ Q_UNUSED(include_merged_revisions);
+ Q_UNUSED(ignore_mimetypes);
+ Q_UNUSED(diffoptions);
+ error = svn_client_blame2(
+ path.path().TOUTF8(),
+ peg.revision(),
+ revisionStart.revision (),
+ revisionEnd.revision (),
+ annotateReceiver,
+ &target,
+ *m_context, // client ctx
+ pool);
+#endif
+ if (error != NULL)
+ {
+ throw ClientException (error);
+ }
+ }
+}
diff --git a/src/svnqt/client_cat.cpp b/src/svnqt/client_cat.cpp
new file mode 100644
index 0000000..fb03f46
--- /dev/null
+++ b/src/svnqt/client_cat.cpp
@@ -0,0 +1,105 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1200
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+// svncpp
+#include "client_impl.hpp"
+
+// Subversion api
+#include "svn_client.h"
+//#include "svn_io.h"
+
+#include "svnqt/exception.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/status.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/svnstream.hpp"
+#include "svnqt/svnfilestream.hpp"
+
+namespace svn
+{
+ QByteArray
+ Client_impl::cat(const Path & path,
+ const Revision & revision,
+ const Revision & peg_revision) throw (ClientException)
+ {
+ svn::stream::SvnByteStream buffer(*m_context);
+ svn_error_t * error = internal_cat(path,revision,peg_revision,buffer);
+ if (error != 0)
+ throw ClientException (error);
+
+ return buffer.content();
+ }
+
+ void
+ Client_impl::cat(svn::stream::SvnStream&buffer,
+ const Path & path,
+ const Revision & revision,
+ const Revision & peg_revision) throw (ClientException)
+ {
+ svn_error_t * error = internal_cat(path,revision,peg_revision,buffer);
+ if (error != 0)
+ throw ClientException (error);
+ }
+
+ void
+ Client_impl::get (const Path & path,
+ const QString & target,
+ const Revision & revision,
+ const Revision & peg_revision) throw (ClientException)
+ {
+ svn::stream::SvnFileOStream buffer(target,*m_context);
+ svn_error_t * error = internal_cat(path,revision,peg_revision,buffer);
+ if (error != 0)
+ throw ClientException (error);
+ }
+
+ svn_error_t * Client_impl::internal_cat(const Path & path,
+ const Revision & revision,
+ const Revision & peg_revision,
+ svn::stream::SvnStream&buffer)
+ {
+ Pool pool;
+ return svn_client_cat2 (buffer,
+ path.path().TOUTF8(),
+ peg_revision.revision (),
+ revision.revision (),
+ *m_context,
+ pool);
+ }
+
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client_diff.cpp b/src/svnqt/client_diff.cpp
new file mode 100644
index 0000000..4074fa2
--- /dev/null
+++ b/src/svnqt/client_diff.cpp
@@ -0,0 +1,184 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1200
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+// svncpp
+#include "svnqt/client_impl.hpp"
+
+// Subversion api
+#include "svn_client.h"
+#include "svn_path.h"
+
+#include "svnqt/exception.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/status.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/helper.hpp"
+#include "diff_data.hpp"
+
+#include <qfile.h>
+#include <qstringlist.h>
+
+#include <apr_xlate.h>
+
+namespace svn
+{
+ QByteArray
+ Client_impl::diff_peg (const Path & tmpPath, const Path & path,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2, const Revision& peg_revision,
+ Depth depth, const bool ignoreAncestry,
+ const bool noDiffDeleted,const bool ignore_contenttype) throw (ClientException)
+ {
+ return diff_peg(tmpPath,path,relativeTo,
+ revision1,revision2,peg_revision,
+ depth,ignoreAncestry,noDiffDeleted,ignore_contenttype,
+ StringArray(),StringArray());
+ }
+
+ QByteArray
+ Client_impl::diff_peg (const Path & tmpPath, const Path & path,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2, const Revision& peg_revision,
+ Depth depth, const bool ignoreAncestry,
+ const bool noDiffDeleted,const bool ignore_contenttype,
+ const StringArray&extra,const StringArray&changelists) throw (ClientException)
+ {
+ Pool pool;
+ svn_error_t * error;
+ const apr_array_header_t * options;
+
+ // svn_client_diff needs an options array, even if it is empty
+ options = extra.array(pool);
+ DiffData ddata(tmpPath,path,revision1,path,revision2);
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ qDebug("pegged diff4 call");
+ error = svn_client_diff_peg4(
+ options,
+ path.cstr(),
+ peg_revision,ddata.r1().revision(),ddata.r2().revision(),
+ relativeTo.length()>0?relativeTo.cstr():QByteArray(0),
+ internal::DepthToSvn(depth),
+ ignoreAncestry,noDiffDeleted,ignore_contenttype,
+ APR_LOCALE_CHARSET,
+ ddata.outFile(),ddata.errFile(),
+ changelists.array(pool),
+ *m_context,
+ pool
+ );
+#else
+ Q_UNUSED(relativeTo);
+ Q_UNUSED(changelists);
+ bool recurse = depth==DepthInfinity;
+ error = svn_client_diff_peg3(
+ options,
+ path.cstr(),
+ peg_revision,ddata.r1().revision(),ddata.r2().revision(),
+ recurse?1:0,ignoreAncestry,noDiffDeleted,ignore_contenttype,
+ APR_LOCALE_CHARSET,
+ ddata.outFile(),ddata.errFile(),
+ *m_context,
+ pool
+ );
+#endif
+ if (error != NULL)
+ {
+ throw ClientException (error);
+ }
+ return ddata.content();
+ }
+
+ QByteArray
+ Client_impl::diff (const Path & tmpPath, const Path & path1,const Path&path2,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2,
+ Depth depth, const bool ignoreAncestry,
+ const bool noDiffDeleted,const bool ignore_contenttype) throw (ClientException)
+ {
+ return diff(tmpPath,path1,path2,relativeTo,
+ revision1,revision2,
+ depth,ignoreAncestry,noDiffDeleted,ignore_contenttype,
+ StringArray(),StringArray());
+ }
+
+ QByteArray
+ Client_impl::diff (const Path & tmpPath, const Path & path1,const Path&path2,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2,
+ Depth depth, const bool ignoreAncestry,
+ const bool noDiffDeleted,const bool ignore_contenttype,
+ const StringArray&extra,const StringArray&changelists) throw (ClientException)
+ {
+
+ Pool pool;
+ svn_error_t * error;
+ const apr_array_header_t * options;
+
+ // svn_client_diff needs an options array, even if it is empty
+ options = extra.array(pool);
+ DiffData ddata(tmpPath,path1,revision1,path2,revision2);
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_diff4(options,
+ path1.cstr (), ddata.r1().revision (),
+ path2.cstr (), ddata.r2().revision (),
+ relativeTo.length()>0?relativeTo.cstr():QByteArray(0),
+ internal::DepthToSvn(depth), ignoreAncestry, noDiffDeleted, ignore_contenttype,
+ APR_LOCALE_CHARSET,
+ ddata.outFile(),ddata.errFile(),
+ changelists.array(pool),
+ *m_context,
+ pool);
+#else
+ Q_UNUSED(changelists);
+ Q_UNUSED(relativeTo);
+ bool recurse = depth==DepthInfinity;
+ // run diff
+ error = svn_client_diff3 (options,
+ path1.cstr (), ddata.r1().revision (),
+ path2.cstr (), ddata.r2().revision (),
+ recurse?1:0, ignoreAncestry, noDiffDeleted, ignore_contenttype,
+ APR_LOCALE_CHARSET,
+ ddata.outFile(),ddata.errFile(),
+ *m_context,
+ pool);
+#endif
+ if (error != NULL)
+ {
+ throw ClientException (error);
+ }
+ return ddata.content();
+
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client_impl.cpp b/src/svnqt/client_impl.cpp
new file mode 100644
index 0000000..74c2850
--- /dev/null
+++ b/src/svnqt/client_impl.cpp
@@ -0,0 +1,123 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1200
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+
+// svncpp
+#include "svnqt/client_impl.hpp"
+#include "svn_opt.h"
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qmap.h>
+#include <qstringlist.h>
+namespace svn
+{
+
+ Client_impl::Client_impl (ContextP context)
+ : Client()
+ {
+ setContext (context);
+ }
+
+ Client_impl::~Client_impl ()
+ {
+ }
+
+ const ContextP
+ Client_impl::getContext () const
+ {
+ return m_context;
+ }
+
+ void
+ Client_impl::setContext (ContextP context)
+ {
+ m_context = context;
+ }
+
+
+ void
+ Client_impl::url2Revision(const QString&revstring,
+ Revision&start,Revision&end)
+ {
+ Pool pool;
+ int n = svn_opt_parse_revision(start,end,revstring.TOUTF8(),pool);
+
+ if (n<0) {
+ start = Revision::UNDEFINED;
+ end = Revision::UNDEFINED;
+ }
+ }
+
+ void Client_impl::url2Revision(const QString&revstring,Revision&start)
+ {
+ if (revstring=="WORKING") {
+ start = Revision::WORKING;
+ } else if (revstring=="BASE"){
+ start = Revision::BASE;
+ } else if (revstring=="START"){
+ start = Revision::START;
+ } else {
+ Revision end;
+ url2Revision(revstring,start,end);
+ }
+ }
+
+ apr_hash_t * Client_impl::map2hash(const PropertiesMap&aMap,const Pool&pool)
+ {
+ if (aMap.count()==0) {
+ return 0;
+ }
+ apr_hash_t * hash = apr_hash_make(pool);
+ PropertiesMap::ConstIterator it;
+ const char*propval;
+ const char*propname;
+ QByteArray s,n;
+ for (it=aMap.begin();it!=aMap.end();++it) {
+#if QT_VERSION < 0x040000
+ s=it.data().TOUTF8();
+#else
+ s=it.value().TOUTF8();
+#endif
+ n=it.key().TOUTF8();
+ propval=apr_pstrndup(pool,s,s.size());
+ propname=apr_pstrndup(pool,n,n.size());
+ apr_hash_set(hash,propname,APR_HASH_KEY_STRING,propval);
+ }
+ return hash;
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client_impl.hpp b/src/svnqt/client_impl.hpp
new file mode 100644
index 0000000..4c3b363
--- /dev/null
+++ b/src/svnqt/client_impl.hpp
@@ -0,0 +1,881 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_CLIENT_IMPL_H_
+#define _SVNCPP_CLIENT_IMPL_H_
+
+#include "svnqt/client.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+// Ignore MSVC 6 compiler warning: debug symbol truncated
+#if defined (_MSC_VER) && _MSC_VER <= 1200
+#pragma warning (disable: 4786)
+#endif
+
+// Ignore MSVC 7, 2005 & 2008 compiler warning: C++ exception specification
+#if defined (_MSC_VER) && _MSC_VER > 1200 && _MSC_VER <= 1550
+#pragma warning (disable: 4290)
+#endif
+
+class QStringList;
+
+namespace svn
+{
+ namespace stream {
+ class SvnStream;
+ }
+
+ /**
+ * Subversion client API.
+ */
+ class SVNQT_NOEXPORT Client_impl:public Client
+ {
+ public:
+ /**
+ * Initializes the primary memory pool.
+ */
+ Client_impl(ContextP context);
+
+ virtual ~Client_impl();
+
+ /**
+ * @return returns the Client context
+ */
+ virtual const ContextP
+ getContext () const;
+
+ /**
+ * sets the client context
+ * you have to make sure the old context
+ * is de-allocated
+ *
+ * @param context new context to use
+ */
+ virtual void
+ setContext (ContextP context);
+
+
+ /**
+ * Enumerates all files/dirs at a given path.
+ *
+ * Throws an exception if an error occurs
+ *
+ * @param path Path to explore.
+ * @param descend Recurse into subdirectories if existant.
+ * @param get_all Return all entries, not just the interesting ones.
+ * @param update Query the repository for updates.
+ * @param no_ignore Disregard default and svn:ignore property ignores.
+ * @param hide_externals don't recurse into external definitions
+ * @param revision list specific revision when browsing remote, on working copies parameter will ignored
+ * @param detailed_remote if on remote listing detailed item info should get if possible
+ * that may slow so should configureable in frontends!
+ * @return vector with Status entries.
+ */
+ virtual StatusEntries
+ status (const Path& path,
+ Depth depth=DepthEmpty,
+ bool get_all = true,
+ bool update = false,
+ bool no_ignore = false,
+ const Revision revision = svn::Revision::HEAD,
+ bool detailed_remote = false,
+ bool hide_externals = false,
+ const StringArray & changelists=StringArray()) throw (ClientException);
+
+ /**
+ * Returns the status of a single file in the path.
+ *
+ * Throws an exception if an error occurs
+ *
+ * @param path File to gather status.
+ * @param update if check against repository if new updates are there (for WC only)
+ * @param revision list specific revision when browsing remote, on working copies parameter will ignored
+ * @return a Status with Statis.isVersioned = FALSE
+ */
+ virtual StatusPtr
+ singleStatus (const Path& path,bool update=false,const Revision revision = svn::Revision::HEAD) throw (ClientException);
+
+ /**
+ * Executes a revision checkout.
+ * @param moduleName name of the module to checkout.
+ * @param destPath destination directory for checkout.
+ * @param revision the revision number to checkout. If the number is -1
+ * then it will checkout the latest revision.
+ * @param peg Revision to look up
+ * @param recurse whether you want it to checkout files recursively.
+ * @param ignore_externals if true don't process externals definitions.
+ * @exception ClientException
+ */
+ virtual svn_revnum_t
+ checkout (const Path& moduleName, const Path & destPath,
+ const Revision & revision,
+ const Revision & peg = Revision::UNDEFINED,
+ svn::Depth depth=DepthInfinity,
+ bool ignore_externals=false,
+ bool overwrite=false
+ ) throw (ClientException);
+
+ /**
+ * relocate wc @a from to @a to
+ * @exception ClientException
+ */
+ virtual void
+ relocate (const Path & path, const QString &from_url,
+ const QString &to_url, bool recurse) throw (ClientException);
+
+ /**
+ * Sets a single file for deletion.
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ remove (const Path & path, bool force,
+ bool keep_local = true,
+ const PropertiesMap&revProps = PropertiesMap()) throw (ClientException);
+
+ /**
+ * Sets files for deletion.
+ *
+ * @param targets targets to delete
+ * @param force force if files are locally modified
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ remove (const Targets & targets,
+ bool force,
+ bool keep_local = true,
+ const PropertiesMap&revProps = PropertiesMap()) throw (ClientException);
+
+ /**
+ * Reverts a couple of files to a pristiner state.
+ * @exception ClientException
+ */
+ virtual void
+ revert (const Targets & targets,
+ Depth depth,
+ const StringArray&changelist=StringArray()
+ ) throw (ClientException);
+
+
+ /**
+ * Adds a file to the repository.
+ * @param path the path to add
+ * @param depth if @a path is a folder add items recursive depending on value if it. Pre-subversion 1.5 DepthInfinity is mapped to recursive, all other to not-recursive.
+ * @param force if true, do not error on already-versioned items.
+ * @param no_ignore if false don't add files or directories that match ignore patterns.
+ * @param add_parents if true, go up to the next versioned folder and add all between path and this folder. Used only with subversion 1.5 or newer
+ * @exception ClientException
+ * @sa svn::Depth
+ */
+ virtual void add (const Path & path, svn::Depth depth,bool force=false, bool no_ignore=false, bool add_parents = true) throw (ClientException);
+
+ /**
+ * Updates the file or directory.
+ * @param path targets.
+ * @param revision the revision number to checkout.
+ * Revision::HEAD will checkout the
+ * latest revision.
+ * @param depth Depthness for operation
+ * @param ignore_externals ignore externals
+ * @param allow_unversioned will operation not fail if there are unversioned items in tree with same name.
+ * @exception ClientException
+ */
+ virtual Revisions
+ update (const Targets & path, const Revision & revision,
+ Depth depth,bool ignore_externals,bool allow_unversioned,
+ bool sticky_depth) throw (ClientException);
+
+ /**
+ * Retrieves the contents for a specific @a revision of
+ * a @a path at @a peg_revision
+ *
+ * @param path path of file or directory
+ * @param peg_revision revision to base the URL
+ * @param revision revision to retrieve
+ * @param peg_revision Revision to look at
+ * @return contents of the file
+ */
+ virtual QByteArray
+ cat (const Path & path,
+ const Revision & revision,
+ const Revision & peg_revision=svn_opt_revision_unspecified) throw (ClientException);
+ /**
+ * Retrieves the contents for a specific @a revision of
+ * a @a path at @a peg_revision
+ *
+ * @param buffer Stream to store content direct
+ * @param path path of file or directory
+ * @param peg_revision revision to base the URL
+ * @param revision revision to retrieve
+ * @exception ClientException
+ */
+ virtual void
+ cat(svn::stream::SvnStream&buffer,
+ const Path & path,
+ const Revision & revision,
+ const Revision & peg_revision) throw (ClientException);
+
+ /**
+ * Retrieves the contents for a specific @a revision of
+ * a @a path at @a peg_revision
+ *
+ * @param path path of file or directory
+ * @param target new (local) name
+ * @param peg_revision revision to base the URL
+ * @param revision revision to retrieve
+ * @param peg_revision Revision to look at
+ */
+ virtual void
+ get (const Path & path,
+ const QString & target,
+ const Revision & revision,
+ const Revision & peg_revision=svn_opt_revision_unspecified) throw (ClientException);
+
+ /**
+ * Retrieves the contents for a specific @a revision of
+ * a @a path and stores the result in @a target
+ *
+ * @param target the container where to store the result
+ * @param path path of file or directory
+ * @param revisionStart revision to retrieve
+ * @param revisionEnd revision to retrieve
+ * @param peg indicates in which revision path is valid
+ */
+ virtual void
+ annotate (AnnotatedFile&target,
+ const Path & path,
+ const Revision & revisionStart,
+ const Revision & revisionEnd,
+ const Revision & peg = Revision::UNDEFINED,
+ const DiffOptions&diffoptions = DiffOptions(),
+ bool ignore_mimetypes = false,
+ bool include_merged_revisions = false
+ ) throw (ClientException);
+
+ /**
+ * Commits changes to the repository. This usually requires
+ * authentication, see Auth.
+ * @return Returns revision transferred or svn::Revision::UNDEFINED if the revision number is invalid.
+ * @param targets files to commit.
+ * @param message log message.
+ * @param depth whether the operation should be done recursively.
+ * @param keep_locks if false unlock items in paths
+ * @param changelist
+ * @param keep_changelist
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ commit (const Targets & targets,
+ const QString& message,
+ svn::Depth depth,bool keep_locks=true,
+ const svn::StringArray&changelist=svn::StringArray(),
+ const PropertiesMap&revProps=PropertiesMap(),
+ bool keep_changelist=false
+ ) throw (ClientException);
+
+ /**
+ * Copies a versioned file with the history preserved.
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ copy (const Path & srcPath,
+ const Revision & srcRevision,
+ const Path & destPath) throw (ClientException);
+ /**
+ * Copies a versioned file with the history preserved.
+ * @since subversion 1.5 api
+ * @see svn_client_copy4
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ copy (const Targets & srcPath,
+ const Revision & srcRevision,
+ const Revision & pegRevision,
+ const Path & destPath,
+ bool asChild=false,bool makeParent=false,const PropertiesMap&revProps=PropertiesMap()) throw (ClientException);
+
+ /**
+ * Moves or renames a file.
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ move (const Path & srcPath,
+ const Path & destPath,
+ bool force) throw (ClientException);
+
+ /**
+ * Moves or renames a file.
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ move (const Targets & srcPath,
+ const Path & destPath,
+ bool force,bool asChild,bool makeParent,const PropertiesMap&revProps=PropertiesMap()) throw (ClientException);
+
+ /**
+ * Creates a directory directly in a repository or creates a
+ * directory on disk and schedules it for addition. If <i>path</i>
+ * is a URL then authentication is usually required, see Auth and
+ * the callback asks for a logmessage.
+ *
+ * @param path
+ * @param message log message. if it is QString::null asks when working on repository
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ mkdir (const Path & path,
+ const QString& message,
+ bool makeParent=true,
+ const PropertiesMap&revProps=PropertiesMap()
+ ) throw (ClientException);
+ /**
+ * Creates a directory directly in a repository or creates a
+ * directory on disk and schedules it for addition. If <i>path</i>
+ * is a URL then authentication is usually required, see Auth and
+ * the callback asks for a logmessage.
+ *
+ * @param targets encoded pathes to create
+ * @param message log message. if it is QString::null asks when working on repository
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ mkdir (const Targets & targets,
+ const QString& message,
+ bool makeParent=true,
+ const PropertiesMap&revProps=PropertiesMap()
+ ) throw (ClientException);
+
+ /**
+ * Recursively cleans up a local directory, finishing any
+ * incomplete operations, removing lockfiles, etc.
+ * @param path a local directory.
+ * @exception ClientException
+ */
+ virtual void
+ cleanup (const Path & path) throw (ClientException);
+
+ /**
+ * Removes the 'conflicted' state on a file.
+ * @exception ClientException
+ */
+ virtual void resolve (const Path & path,Depth depth,const ConflictResult&resolution=ConflictResult()) throw (ClientException);
+
+ /**
+ * Exports the contents of either a subversion repository into a
+ * 'clean' directory (meaning a directory with no administrative
+ * directories).
+ * @exception ClientException
+ * @param srcPath source path
+ * @param destPath a destination path that must not already exist.
+ * @param revision revision to use for the export
+ * @param peg the revision where the path is first looked up when exporting from a repository.
+ * @param overwrite overwrite existing files
+ * @param native_eol Either "LF", "CR" or "CRLF" or NULL.
+ * @param ignore_externals don't process externals definitions as part of this operation.
+ * @param recurse if true, export recursively. Otherwise, export just the directory represented by from and its immediate non-directory children.
+ */
+ virtual svn_revnum_t
+ doExport (const Path & srcPath,
+ const Path & destPath,
+ const Revision & revision,
+ const Revision & peg = Revision::UNDEFINED,
+ bool overwrite=false,
+ const QString&native_eol=QString::null,
+ bool ignore_externals = false,
+ svn::Depth depth=svn::DepthInfinity
+ ) throw (ClientException);
+
+ /**
+ * Update local copy to mirror a new url. This excapsulates the
+ * svn_client_switch() client method.
+ * @exception ClientException
+ */
+ virtual svn_revnum_t
+ doSwitch (
+ const Path & path, const QString& url,
+ const Revision & revision,
+ Depth depth,
+ const Revision & peg=Revision::UNDEFINED,
+ bool sticky_depth = true,
+ bool ignore_externals=false,
+ bool allow_unversioned=false
+ ) throw (ClientException);
+
+ /**
+ * Import file or directory PATH into repository directory URL at
+ * head. This usually requires authentication, see Auth.
+ * @param path path to import
+ * @param url
+ * @param message log message.
+ * @param depth kind of recurse operation
+ * @param no_ignore if false, don't add items matching global ignore pattern
+ * @param no_unknown_nodetype if true ignore files type not known like pipes or device files
+ * @exception ClientException
+ */
+ virtual svn::Revision
+ import (const Path & path, const QString& url,
+ const QString& message,
+ svn::Depth depth,
+ bool no_ignore,bool no_unknown_nodetype,
+ const PropertiesMap&revProps=PropertiesMap()) throw (ClientException);
+
+ /**
+ * Merge changes from two paths into a new local path.
+ * @exception ClientException
+ */
+ virtual void
+ merge (const Path & path1, const Revision & revision1,
+ const Path & path2, const Revision & revision2,
+ const Path & localPath, bool force,
+ Depth depth,
+ bool notice_ancestry=false,
+ bool dry_run=false,
+ bool record_only=false,
+ const StringArray&merge_options=StringArray()
+ ) throw (ClientException);
+
+ virtual void
+ merge_peg(const Path&src,
+ const RevisionRanges&ranges,
+ const Revision&peg,
+ const Path&targetWc,
+ Depth depth,
+ bool notice_ancestry=false,
+ bool dry_run=false,
+ bool force=false,
+ bool record_only=false,
+ const StringArray&merge_options=StringArray()
+ ) throw (ClientException);
+
+ virtual void
+ merge_peg(const Path&src,
+ const RevisionRange&range,
+ const Revision&peg,
+ const Path&targetWc,
+ Depth depth,
+ bool notice_ancestry,
+ bool dry_run,
+ bool force,
+ const StringArray&merge_options
+ ) throw (ClientException);
+
+ /**
+ * Retrieve information for the given path
+ * remote or local. Only gives with subversion 1.2
+ * usefull results
+ *
+ * @param path path for info
+ * @param rec recursive (if dir)
+ * @param rev for which revision
+ * @param peg_revision peg revision
+ * @return InfoEntries
+ * @since subversion 1.2
+ */
+ virtual InfoEntries
+ info(const Path &path,
+ Depth depth,
+ const Revision & rev,
+ const Revision & peg_revision=svn_opt_revision_unspecified,
+ const StringArray&changelists=StringArray()
+ ) throw (ClientException);
+ /**
+ * Retrieve log information for the given path
+ * Loads the log messages result set. The first
+ * entry is the youngest revision.
+ *
+ * You can use the constants Revision::START and
+ * Revision::HEAD
+ *
+ * @param path
+ * @param revisionStart Start revision.
+ * @param revisionEnd End revision
+ * @param revisionPeg Revision where path is valid.
+ * @param discoverChangedPaths Should changed pathes transferred
+ * @param strictNodeHistory
+ * @param limit the maximum log entries count.
+ * @param include_merged_revisions log information for revisions which have been merged to targets will also be returned. (subversion 1.5)
+ * @return a vector with log entries
+ */
+ virtual LogEntriesPtr
+ log (const Path& path, const Revision & revisionStart,
+ const Revision & revisionEnd,
+ const Revision & revisionPeg,
+ bool discoverChangedPaths=false,
+ bool strictNodeHistory=true,int limit=0,
+ bool include_merged_revisions = false,
+ const StringArray&revprops=StringArray()
+ ) throw (ClientException);
+ /**
+ * Retrieve log information for the given path
+ * Loads the log messages result set. Result will stored
+ * in a map where the key is the revision number
+ *
+ * You can use the constants Revision::START and
+ * Revision::HEAD
+ *
+ * @param path
+ * @param revisionStart
+ * @param revisionEnd
+ * @param revisionPeg Revision where path is valid.
+ * @param target the logmap where to store the entries
+ * @param discoverChangedPaths
+ * @param strictNodeHistory
+ * @param limit (ignored when subversion 1.1 API)
+ * @return true if success
+ */
+ virtual bool
+ log (const Path& path, const Revision & revisionStart,
+ const Revision & revisionEnd,
+ LogEntriesMap&target,
+ const Revision & revisionPeg,
+ bool discoverChangedPaths,
+ bool strictNodeHistory,int limit,
+ bool include_merged_revisions = false,
+ const StringArray&revprops=StringArray()
+ ) throw (ClientException);
+
+ /**
+ * Produce diff output which describes the delta between
+ * @a path/@a revision1 and @a path/@a revision2. @a path
+ * can be either a working-copy path or a URL.
+ *
+ * A ClientException will be thrown if either @a revision1 or
+ * @a revision2 has an `unspecified' or unrecognized `kind'.
+ *
+ * @param tmpPath prefix for a temporary directory needed by diff.
+ * Filenames will have ".tmp" and similar added to this prefix in
+ * order to ensure uniqueness.
+ * @param path path of the file.
+ * @param revision1 one of the revisions to check.
+ * @param revision2 the other revision.
+ * @param recurse whether the operation should be done recursively.
+ * @param ignoreAncestry whether the files will be checked for
+ * relatedness.
+ * @param noDiffDeleted if true, no diff output will be generated on deleted files.
+ * @param ignore_contenttype if true generate diff even the items are marked as binaries
+ * @param extra extra options for diff ("-b", "-w","--ignore-eol-style")
+ * @return delta between the files
+ * @exception ClientException
+ */
+ virtual QByteArray
+ diff_peg (const Path & tmpPath, const Path & path,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2, const Revision& peg_revision,
+ Depth depth, bool ignoreAncestry,
+ bool noDiffDeleted,bool ignore_contenttype,
+ const StringArray&extra,
+ const StringArray&changelists
+ )
+ throw (ClientException);
+
+ /**
+ * Same as other diff but extra options and changelists always set to empty list.
+ */
+ virtual QByteArray
+ diff_peg (const Path & tmpPath, const Path & path,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2, const Revision& peg_revision,
+ Depth depth, bool ignoreAncestry,
+ bool noDiffDeleted,bool ignore_contenttype)
+ throw (ClientException);
+
+ /**
+ * Produce diff output which describes the delta between
+ * @a path1/@a revision1 and @a path2/@a revision2. @a path2
+ * can be either a working-copy path or a URL.
+ *
+ * A ClientException will be thrown if either @a revision1 or
+ * @a revision2 has an `unspecified' or unrecognized `kind'.
+ *
+ * @param tmpPath prefix for a temporary directory needed by diff.
+ * Filenames will have ".tmp" and similar added to this prefix in
+ * order to ensure uniqueness.
+ * @param path1 first file or folder to diff.
+ * @param path2 second file or folder to diff.
+ * @param revision1 one of the revisions to check (path1).
+ * @param revision2 the other revision (path2).
+ * @param recurse whether the operation should be done recursively.
+ * @param ignoreAncestry whether the files will be checked for
+ * relatedness.
+ * @param noDiffDeleted if true, no diff output will be generated on deleted files.
+ * @param ignore_contenttype if true generate diff even the items are marked as binaries
+ * @param extra extra options for diff ("-b", "-w","--ignore-eol-style")
+ * @return delta between the files
+ * @exception ClientException
+ */
+ virtual QByteArray
+ diff (const Path & tmpPath, const Path & path1,const Path & path2,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2,
+ Depth depth, bool ignoreAncestry,
+ bool noDiffDeleted,bool ignore_contenttype,
+ const StringArray&extra,
+ const StringArray&changelists
+ )
+ throw (ClientException);
+
+ /**
+ * Same as other diff but extra options always set to empty list.
+ */
+ virtual QByteArray
+ diff (const Path & tmpPath, const Path & path1,const Path & path2,const Path&relativeTo,
+ const Revision & revision1, const Revision & revision2,
+ Depth depth, bool ignoreAncestry,
+ bool noDiffDeleted,bool ignore_contenttype)
+ throw (ClientException);
+
+ /**
+ * lists entries in @a pathOrUrl no matter whether local or
+ * repository
+ *
+ * @param pathOrUrl
+ * @param revision
+ * @param peg at wich revision path exists
+ * @param depth @sa svn::Depth
+ * @param retrieve_locks check for REPOSITORY locks while listing
+ * @return a vector of directory entries, each with
+ * a relative path (only filename)
+ */
+ virtual DirEntries
+ list (const Path& pathOrUrl,
+ const Revision& revision,
+ const Revision& peg,
+ svn::Depth depth,bool retrieve_locks) throw (ClientException);
+
+ /**
+ * lists properties in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param revision
+ * @param peg most case should set to @a revision
+ * @param recurse
+ * @return PropertiesList
+ */
+ virtual PathPropertiesMapListPtr
+ proplist(const Path &path,
+ const Revision &revision,
+ const Revision &peg,
+ Depth depth=DepthEmpty,
+ const StringArray&changelists=StringArray());
+
+ /**
+ * lists one property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param path
+ * @param revision
+ * @param peg most case should set to @a revision
+ * @param recurse
+ * @return PathPropertiesMapList
+ */
+ virtual QPair<QLONG,PathPropertiesMapList>
+ propget(const QString& propName,
+ const Path &path,
+ const Revision &revision,
+ const Revision &peg,
+ Depth depth = svn::DepthEmpty,
+ const StringArray&changelists=StringArray());
+
+ /**
+ * set property in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param propName
+ * @param propValue
+ * @param recurse
+ * @param skip_check if true skip validity checks
+ * @return PropertiesList
+ */
+ virtual void
+ propset(const QString& propName,
+ const QString& propValue,
+ const Path &path,
+ Depth depth=DepthEmpty,
+ bool skip_check=false,
+ const Revision&base_revision=Revision::UNDEFINED,
+ const StringArray&changelists=StringArray(),
+ const PropertiesMap&revProps=PropertiesMap()
+ );
+
+ /**
+ * delete property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param path
+ * @param revision
+ * @param recurse
+ */
+ virtual void
+ propdel(const QString& propName,
+ const Path &path,
+ Depth depth=DepthEmpty,
+ bool skip_check=false,
+ const Revision&base_revision=Revision::UNDEFINED,
+ const StringArray&changelists=StringArray());
+
+
+ /**
+ * lists revision properties in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param revision
+ * @return PropertiesList
+ */
+ virtual QPair<QLONG,PropertiesMap>
+ revproplist(const Path &path,
+ const Revision &revision);
+
+ /**
+ * lists one revision property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param path
+ * @param revision
+ * @return PropertiesList
+ */
+ QPair<QLONG,QString>
+ revpropget(const QString& propName,
+ const Path &path,
+ const Revision &revision);
+
+ /**
+ * set revision property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param propValue
+ * @param path
+ * @param revision
+ * @param force
+ * @return Revision
+ */
+ virtual QLONG
+ revpropset(const QString& propName,
+ const QString& propValue,
+ const Path &path,
+ const Revision &revision,
+ bool force=false);
+
+ /**
+ * delete revision property in @a path no matter whether local or
+ * repository
+ *
+ * @param propName
+ * @param path
+ * @param revision
+ * @param force
+ * @return Revision
+ */
+ virtual QLONG
+ revpropdel(const QString& propName,
+ const Path &path,
+ const Revision &revision,
+ bool force=false);
+
+ /**
+ * lock files in repository or working copy
+ * @param targets items to be locked
+ * @param message if non null stored with each lock in repository
+ * @param steal_lock if true locks in wc will stolen.
+ * @since subversion 1.2
+ */
+ virtual void
+ lock (const Targets & targets,
+ const QString& message,
+ bool steal_lock) throw (ClientException);
+ /**
+ * unlock files in repository or working copy
+ * @param targets items to unlock
+ * @param break_lock ignore any errors
+ */
+ virtual void
+ unlock (const Targets&targets,
+ bool break_lock) throw (ClientException);
+
+ virtual void
+ url2Revision(const QString&revstring,
+ Revision&start,Revision&end);
+ virtual void
+ url2Revision(const QString&revstring,
+ Revision&start);
+
+ struct sBaton {
+ Context*m_context;
+ void*m_data;
+ void*m_revstack;
+ };
+
+ struct propBaton {
+ Context*m_context;
+ PathPropertiesMapList*resultlist;
+ };
+
+ private:
+ ContextP m_context;
+
+ /**
+ * disallow assignment operator
+ */
+ Client_impl & operator= (const Client &);
+
+ /**
+ * disallow copy constructor
+ */
+ Client_impl (const Client &);
+
+ DirEntries
+ list_simple(const Path& pathOrUrl,
+ const Revision& revision,
+ const Revision& peg,
+ bool recurse) throw (ClientException);
+ DirEntries
+ list_locks(const Path& pathOrUrl,
+ const Revision& revision,
+ const Revision& peg,
+ bool recurse) throw (ClientException);
+
+ svn_error_t * internal_cat(const Path & path,
+ const Revision & revision,
+ const Revision & peg_revision,
+ svn::stream::SvnStream&);
+
+ apr_hash_t * map2hash(const PropertiesMap&,const Pool&);
+ };
+
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client_lock.cpp b/src/svnqt/client_lock.cpp
new file mode 100644
index 0000000..b70223d
--- /dev/null
+++ b/src/svnqt/client_lock.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+// svncpp
+#include "client_impl.hpp"
+
+// subversion api
+#include "svn_client.h"
+
+#include "svnqt/exception.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/targets.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+namespace svn
+{
+
+ void
+ Client_impl::lock (const Targets & targets,
+ const QString& message,
+ bool steal_lock) throw (ClientException)
+ {
+ Pool pool;
+ svn_error_t * error =
+ svn_client_lock(const_cast<apr_array_header_t*> (targets.array (pool)),
+ message.TOUTF8(),
+ steal_lock,
+ *m_context,
+ pool);
+ if(error != NULL)
+ throw ClientException (error);
+ }
+
+ void
+ Client_impl::unlock (const Targets&targets,
+ bool break_lock) throw (ClientException)
+ {
+ Pool pool;
+ svn_error_t * error =
+ svn_client_unlock(const_cast<apr_array_header_t*> (targets.array (pool)),
+ break_lock,
+ *m_context,
+ pool);
+ if(error != NULL)
+ throw ClientException (error);
+ }
+}
diff --git a/src/svnqt/client_ls.cpp b/src/svnqt/client_ls.cpp
new file mode 100644
index 0000000..897a4d8
--- /dev/null
+++ b/src/svnqt/client_ls.cpp
@@ -0,0 +1,237 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1200
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+
+
+// svncpp
+#include "svnqt/client_impl.hpp"
+
+// subversion api
+#include "svn_client.h"
+#include "svn_path.h"
+#include "svn_sorts.h"
+//#include "svn_utf.h"
+
+#include "svnqt/dirent.hpp"
+#include "svnqt/exception.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include "svnqt/helper.hpp"
+
+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);
+}
+
+namespace svn
+{
+
+ DirEntries
+ Client_impl::list_simple(const Path& _p,
+ const Revision& revision,
+ const Revision& peg,
+ bool recurse) throw (ClientException)
+ {
+ Pool pool;
+
+ apr_hash_t * hash;
+ /* don't want the lock hashs, so we simply use ls2 on svn 1.3, too.
+ * there is that method a cast to ls3 with lock_hash == 0
+ */
+ svn_error_t * error =
+ svn_client_ls2 (&hash,
+ _p.cstr(),
+ peg.revision(),
+ revision.revision(),
+ recurse,
+ *m_context,
+ pool);
+
+ if (error != 0)
+ throw ClientException (error);
+
+ apr_array_header_t *
+ array = svn_sort__hash (
+ hash, compare_items_as_paths, pool);
+
+ DirEntries entries;
+
+ for (int i = 0; i < array->nelts; ++i)
+ {
+ const char *entryname;
+ svn_dirent_t *dirent;
+ svn_sort__item_t *item;
+
+ item = &APR_ARRAY_IDX (array, i, svn_sort__item_t);
+
+ entryname = static_cast<const char *>(item->key);
+
+ dirent = static_cast<svn_dirent_t *>
+ (apr_hash_get (hash, entryname, item->klen));
+
+ entries.push_back (new DirEntry(QString::FROMUTF8(entryname), dirent));
+ }
+
+ return entries;
+ }
+
+ DirEntries
+ Client_impl::list_locks(const Path& pathOrUrl,
+ const Revision& revision,
+ const Revision& peg,
+ bool recurse) throw (ClientException)
+ {
+ Pool pool;
+
+ apr_hash_t * hash;
+ apr_hash_t * lock_hash;
+
+ svn_error_t * error =
+ svn_client_ls3 (&hash,
+ &lock_hash,
+ pathOrUrl.cstr(),
+ peg,
+ revision,
+ recurse,
+ *m_context,
+ pool);
+
+ if (error != 0)
+ throw ClientException (error);
+
+ apr_array_header_t *
+ array = svn_sort__hash (
+ hash, compare_items_as_paths, pool);
+
+ DirEntries entries;
+
+ for (int i = 0; i < array->nelts; ++i)
+ {
+ const char *entryname;
+ svn_dirent_t *dirent;
+ svn_lock_t * lockent;
+ svn_sort__item_t *item;
+
+ item = &APR_ARRAY_IDX (array, i, svn_sort__item_t);
+
+ entryname = static_cast<const char *>(item->key);
+
+ dirent = static_cast<svn_dirent_t *>
+ (apr_hash_get (hash, entryname, item->klen));
+ lockent = static_cast<svn_lock_t *>
+ (apr_hash_get(lock_hash,entryname,item->klen));
+ entries.push_back (new DirEntry(QString::FROMUTF8(entryname), dirent,lockent));
+ }
+
+ return entries;
+ }
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ static svn_error_t * s_list_func
+ (void * baton,const char*path,const svn_dirent_t*dirent,const svn_lock_t*lock,const char* abs_path,apr_pool_t*)
+ {
+ Q_UNUSED(abs_path);
+ if (!baton || !path || !dirent) {
+ return 0;
+ }
+ /* check every loop for cancel of operation */
+ Client_impl::sBaton * l_baton = (Client_impl::sBaton*)baton;
+ Context*l_context = l_baton->m_context;
+ DirEntries*entries = static_cast<DirEntries*>(l_baton->m_data);
+ svn_client_ctx_t*ctx = l_context->ctx();
+ if (ctx&&ctx->cancel_func) {
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ }
+ entries->push_back(new DirEntry(QString::FROMUTF8(path),dirent,lock));
+ return 0;
+ }
+#endif
+
+ DirEntries
+ Client_impl::list(const Path& pathOrUrl,
+ const Revision& revision,
+ const Revision& peg,
+ Depth depth,bool retrieve_locks) throw (ClientException)
+ {
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ sBaton _baton;
+ Pool pool;
+ DirEntries entries;
+ _baton.m_data = &entries;
+ _baton.m_context=m_context;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_error_t * error = svn_client_list2(pathOrUrl.cstr(),
+ peg,
+ revision,
+ svn::internal::DepthToSvn(depth),
+ SVN_DIRENT_ALL,
+ retrieve_locks,
+ s_list_func,
+ &_baton,
+ *m_context,
+ pool
+ );
+#else
+ bool recurse = depth==DepthInfinity;
+ svn_error_t * error = svn_client_list(pathOrUrl.cstr(),
+ peg,
+ revision,
+ recurse,
+ SVN_DIRENT_ALL,
+ retrieve_locks,
+ s_list_func,
+ &_baton,
+ *m_context,
+ pool
+ );
+#endif
+ if (error != 0) {
+ throw ClientException (error);
+ }
+ return entries;
+#else
+ if (!retrieve_locks) {
+ return list_simple(pathOrUrl,revision,peg,depth==DepthInfinity);
+ } else {
+ return list_locks(pathOrUrl,revision,peg,depth==DepthInfinity);
+ }
+#endif
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client_merge.cpp b/src/svnqt/client_merge.cpp
new file mode 100644
index 0000000..0d84cc2
--- /dev/null
+++ b/src/svnqt/client_merge.cpp
@@ -0,0 +1,180 @@
+#include "svnqt/client_impl.hpp"
+
+// subversion api
+#include "svn_client.h"
+
+#include "svnqt/exception.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/targets.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/stringarray.hpp"
+
+#include "svnqt/helper.hpp"
+
+namespace svn
+{
+void Client_impl::merge (const Path & path1, const Revision & revision1,
+ const Path & path2, const Revision & revision2,
+ const Path & localPath,
+ bool force,
+ Depth depth,
+ bool notice_ancestry,
+ bool dry_run,
+ bool record_only,
+ const StringArray&merge_options
+ ) throw (ClientException)
+{
+ Pool pool;
+ svn_error_t * error = 0;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_merge3(path1.cstr (),
+ revision1.revision (),
+ path2.cstr (),
+ revision2.revision (),
+ localPath.cstr (),
+ internal::DepthToSvn(depth),
+ !notice_ancestry,
+ force,
+ record_only,
+ dry_run,
+ merge_options.array(pool),
+ *m_context,
+ pool);
+#else
+ bool recurse = depth==DepthInfinity;
+ Q_UNUSED(record_only);
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4))
+ error = svn_client_merge2(path1.cstr (),
+ revision1.revision (),
+ path2.cstr (),
+ revision2.revision (),
+ localPath.cstr (),
+ recurse,
+ !notice_ancestry,
+ force,
+ dry_run,
+ merge_options.array(pool),
+ *m_context,
+ pool);
+#else
+ Q_UNUSED(merge_options);
+ error = svn_client_merge(path1.cstr (),
+ revision1.revision (),
+ path2.cstr (),
+ revision2.revision (),
+ localPath.cstr (),
+ recurse,
+ !notice_ancestry,
+ force,
+ dry_run,
+ *m_context,
+ pool);
+#endif
+#endif
+
+ if(error != 0) {
+ throw ClientException (error);
+ }
+ }
+
+ void Client_impl::merge_peg(const Path&src,
+ const RevisionRanges&ranges,
+ const Revision&peg,
+ const Path&targetWc,
+ Depth depth,
+ bool notice_ancestry,
+ bool dry_run,
+ bool force,
+ bool record_only,
+ const StringArray&merge_options
+ ) throw (ClientException)
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ Pool pool;
+ internal::RevisionRangesToHash _rhash(ranges);
+
+ svn_error_t*error;
+
+ error = svn_client_merge_peg3(
+ src.cstr(),
+ _rhash.array(pool),
+ peg,
+ targetWc.cstr(),
+ internal::DepthToSvn(depth),
+ !notice_ancestry,
+ force,
+ record_only,
+ dry_run,
+ merge_options.array(pool),
+ *m_context,
+ pool
+ );
+ if(error != 0) {
+ throw ClientException (error);
+ }
+#else
+ Q_UNUSED(record_only);
+ for (unsigned long i=0;i<ranges.count();++i) {
+ merge_peg(src,ranges[i],peg,targetWc,depth,notice_ancestry,dry_run,force,merge_options);
+ }
+#endif
+ }
+
+ void Client_impl::merge_peg(const Path&src,
+ const RevisionRange&range,
+ const Revision&peg,
+ const Path&targetWc,
+ Depth depth,
+ bool notice_ancestry,
+ bool dry_run,
+ bool force,
+ const StringArray&merge_options
+ ) throw (ClientException)
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ RevisionRanges ranges;
+ ranges.append(range);
+ merge_peg(src,ranges,peg,targetWc,depth,notice_ancestry,dry_run,force,false,merge_options);
+#else
+ Pool pool;
+ bool recurse=depth==DepthInfinity;
+ svn_error_t*error;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_merge_peg2(
+ src.cstr(),
+ range.first,
+ range.second,
+ peg.revision(),
+ targetWc.cstr(),
+ recurse,
+ !notice_ancestry,
+ force,
+ dry_run,
+ merge_options.array(pool),
+ *m_context,
+ pool
+ );
+#else
+ Q_UNUSED(merge_options);
+ error = svn_client_merge_peg(
+ src.cstr(),
+ range.first,
+ range.second,
+ peg.revision(),
+ targetWc.cstr(),
+ recurse,
+ !notice_ancestry,
+ force,
+ dry_run,
+ *m_context,
+ pool
+ );
+#endif
+ if(error != 0) {
+ throw ClientException (error);
+ }
+#endif
+ }
+
+}
diff --git a/src/svnqt/client_modify.cpp b/src/svnqt/client_modify.cpp
new file mode 100644
index 0000000..352760b
--- /dev/null
+++ b/src/svnqt/client_modify.cpp
@@ -0,0 +1,722 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1200
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+// svncpp
+#include "svnqt/client_impl.hpp"
+
+// subversion api
+#include "svn_client.h"
+
+#include "svnqt/exception.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/targets.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/stringarray.hpp"
+
+#include "svnqt/helper.hpp"
+
+namespace svn
+{
+ svn_revnum_t
+ Client_impl::checkout (const Path& url, const Path & destPath,
+ const Revision & revision,
+ const Revision & peg,
+ svn::Depth depth,
+ bool ignore_externals,
+ bool overwrite
+ ) throw (ClientException)
+ {
+ Pool subPool;
+ svn_revnum_t revnum = 0;
+ Path up(url);
+ svn_error_t * error = 0;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_checkout3(&revnum,
+ up.cstr(),
+ destPath.cstr(),
+ peg.revision(),
+ revision.revision (),
+ internal::DepthToSvn(depth),
+ ignore_externals,
+ overwrite,
+ *m_context,
+ subPool);
+#else
+ bool recurse = depth==DepthInfinity;
+ Q_UNUSED(overwrite);
+ error = svn_client_checkout2(&revnum,
+ up.cstr(),
+ destPath.cstr(),
+ peg.revision(),
+ revision.revision (),
+ recurse,
+ ignore_externals,
+ *m_context,
+ subPool);
+#endif
+ if(error != NULL)
+ throw ClientException (error);
+ return revnum;
+ }
+
+ Revision Client_impl::remove (const Path & path,bool force,
+ bool keep_local,
+ const PropertiesMap&revProps) throw (ClientException)
+ {
+ Targets targets (path.path());
+ return remove(targets,force,keep_local,revProps);
+ }
+
+ Revision
+ Client_impl::remove (const Targets & targets,
+ bool force,
+ bool keep_local,
+ const PropertiesMap&revProps
+ ) throw (ClientException)
+ {
+ Pool pool;
+
+ svn_commit_info_t *commit_info = 0;
+
+ svn_error_t * error =
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_client_delete3(
+ &commit_info,
+ targets.array(pool),
+ force,
+ keep_local,
+ map2hash(revProps,pool),
+ *m_context,
+ pool
+ );
+#else
+ svn_client_delete2
+ (&commit_info,
+ const_cast<apr_array_header_t*> (targets.array (pool)),
+ force,
+ *m_context,
+ pool);
+ Q_UNUSED(keep_local);
+ Q_UNUSED(revProps);
+#endif
+ if(error != 0) {
+ throw ClientException (error);
+ }
+ if (commit_info) {
+ return commit_info->revision;
+ }
+ return Revision::UNDEFINED;
+ }
+
+ void
+ Client_impl::revert (const Targets & targets,
+ Depth depth,
+ const StringArray&changelist
+ ) throw (ClientException)
+ {
+ Pool pool;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_error_t * error =
+ svn_client_revert2 ((targets.array (pool)),
+ internal::DepthToSvn(depth),
+ changelist.array(pool),
+ *m_context,
+ pool);
+
+#else
+ bool recurse = depth==DepthInfinity;
+ Q_UNUSED(changelist);
+ svn_error_t * error =
+ svn_client_revert ((targets.array (pool)),
+ recurse,
+ *m_context,
+ pool);
+#endif
+ if(error != NULL) {
+ throw ClientException (error);
+ }
+ }
+
+ void
+ Client_impl::add (const Path & path,
+ svn::Depth depth,bool force, bool no_ignore, bool add_parents) throw (ClientException)
+ {
+ Pool pool;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_error_t * error =
+ svn_client_add4(path.cstr (),
+ internal::DepthToSvn(depth),
+ force,
+ no_ignore,
+ add_parents,
+ *m_context,
+ pool);
+#else
+ Q_UNUSED(add_parents);
+ svn_error_t * error =
+ svn_client_add3 (path.cstr (),
+ depth==DepthInfinity,
+ force,
+ no_ignore,
+ *m_context,
+ pool);
+#endif
+ if(error != NULL)
+ throw ClientException (error);
+ }
+
+ Revisions
+ Client_impl::update (const Targets & path,
+ const Revision & revision,
+ Depth depth,
+ bool ignore_externals,
+ bool allow_unversioned,
+ bool sticky_depth
+ ) throw (ClientException)
+ {
+ Pool pool;
+ Revisions resulting;
+ svn_error_t * error;
+
+ apr_pool_t *apr_pool = pool.pool();
+ apr_array_header_t *apr_revisions = apr_array_make (apr_pool,
+ path.size(),
+ sizeof (svn_revnum_t));
+ if (depth==DepthUnknown) {
+ depth=DepthInfinity;
+ }
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_update3(&apr_revisions,path.array(pool),revision,internal::DepthToSvn(depth),sticky_depth,ignore_externals,allow_unversioned,*m_context,pool);
+#else
+ bool recurse = depth==DepthInfinity;
+ Q_UNUSED(sticky_depth);
+ Q_UNUSED(allow_unversioned);
+ error = svn_client_update2(&apr_revisions,path.array(pool),revision,recurse,ignore_externals,*m_context,pool);
+#endif
+ if (error!=NULL) {
+ throw ClientException(error);
+ }
+ for (int i = 0; i < apr_revisions->nelts; ++i)
+ {
+ svn_revnum_t * _rev =
+ &APR_ARRAY_IDX (apr_revisions, i, svn_revnum_t);
+
+ resulting.push_back((*_rev));
+ }
+ return resulting;
+ }
+
+ svn::Revision
+ Client_impl::commit (const Targets & targets, const QString& message,
+ svn::Depth depth,bool keep_locks,
+ const svn::StringArray&changelist,
+ const PropertiesMap&revProps,
+ bool keep_changelist) throw (ClientException)
+ {
+ Pool pool;
+
+ m_context->setLogMessage (message);
+ svn_commit_info_t *commit_info = NULL;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_error_t * error =
+ svn_client_commit4 (
+ &commit_info,
+ targets.array (pool),
+ internal::DepthToSvn(depth),
+ keep_locks,
+ keep_changelist,
+ changelist.array(pool),
+ map2hash(revProps,pool),
+ *m_context,
+ pool);
+#else
+ Q_UNUSED(changelist);
+ Q_UNUSED(keep_changelist);
+ Q_UNUSED(revProps);
+ bool recurse = depth==DepthInfinity;
+
+ svn_error_t * error =
+ svn_client_commit3
+ (&commit_info,
+ targets.array (pool),
+ recurse,
+ keep_locks,
+ *m_context,
+ pool);
+#endif
+ if (error != NULL) {
+ throw ClientException (error);
+ }
+
+ if (commit_info && SVN_IS_VALID_REVNUM (commit_info->revision))
+ return (commit_info->revision);
+
+ return svn::Revision::UNDEFINED;
+ }
+
+ Revision
+ Client_impl::copy(const Targets & srcPaths,
+ const Revision & srcRevision,
+ const Revision &pegRevision,
+ const Path & destPath,
+ bool asChild,bool makeParent,
+ const PropertiesMap&revProps
+ ) throw (ClientException)
+ {
+ if (srcPaths.size()<1)
+ {
+ throw ClientException("Wrong size of sources.");
+ }
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ Pool pool;
+ svn_commit_info_t *commit_info = 0L;
+ apr_array_header_t * sources = apr_array_make(pool,srcPaths.size(),sizeof(svn_client_copy_source_t *));
+ for (size_t j=0;j<srcPaths.size();++j)
+ {
+ svn_client_copy_source_t* source = (svn_client_copy_source_t*)apr_palloc(pool, sizeof(svn_client_copy_source_t));
+ source->path = apr_pstrdup(pool,srcPaths[j].path().TOUTF8());
+ source->revision=srcRevision.revision();
+ source->peg_revision=pegRevision.revision();
+ APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = source;
+ }
+ svn_error_t * error =
+ svn_client_copy4(&commit_info,
+ sources,
+ destPath.cstr(),
+ asChild,makeParent,map2hash(revProps,pool),*m_context,pool);
+ if (error!=0){
+ throw ClientException (error);
+ }
+ if (commit_info) {
+ return commit_info->revision;
+ }
+ return Revision::UNDEFINED;
+#else
+ Q_UNUSED(asChild);
+ Q_UNUSED(makeParent);
+ Q_UNUSED(revProps);
+ Q_UNUSED(pegRevision);
+ Revision rev;
+ if (srcPaths.size()>1 && !asChild)
+ {
+ throw ClientException("Multiple sources not allowed");
+ }
+
+ Path _dest;
+ QString base,dir;
+ for (size_t j=0;j<srcPaths.size();++j)
+ {
+ _dest=destPath;
+ if (asChild) {
+ srcPaths[j].split(dir,base);
+ _dest.addComponent(base);
+ }
+ rev = copy(srcPaths[j],srcRevision,_dest);
+ }
+ return rev;
+#endif
+ }
+
+ Revision
+ Client_impl::copy (const Path & srcPath,
+ const Revision & srcRevision,
+ const Path & destPath) throw (ClientException)
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ return copy(srcPath,srcRevision,srcRevision,destPath,true,false);
+#else
+ Pool pool;
+ svn_commit_info_t *commit_info = NULL;
+ svn_error_t * error =
+ svn_client_copy2
+ (&commit_info,
+ srcPath.cstr (),
+ srcRevision.revision (),
+ destPath.cstr (),
+ *m_context,
+ pool);
+
+ if(error != 0) {
+ throw ClientException (error);
+ }
+ if (commit_info) {
+ return commit_info->revision;
+ }
+ return Revision::UNDEFINED;
+#endif
+ }
+
+ svn::Revision Client_impl::move (const Path & srcPath,
+ const Path & destPath,
+ bool force) throw (ClientException)
+ {
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ return move(srcPath,destPath,force,false,false,PropertiesMap());
+#else
+ Pool pool;
+ svn_commit_info_t *commit_info = 0;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4))
+ svn_error_t * error = svn_client_move4
+#else
+ svn_error_t * error = svn_client_move3
+#endif
+ (&commit_info,
+ srcPath.cstr (),
+ destPath.cstr (),
+ force,
+ *m_context,
+ pool);
+
+ if(error != 0) {
+ throw ClientException (error);
+ }
+ if (commit_info) {
+ return commit_info->revision;
+ }
+ return Revision::UNDEFINED;
+#endif
+ }
+
+ svn::Revision Client_impl::move (
+ const Targets & srcPaths,
+ const Path & destPath,
+ bool force,
+ bool asChild,
+ bool makeParent,
+ const PropertiesMap&revProps) throw (ClientException)
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ Pool pool;
+ svn_commit_info_t *commit_info = 0;
+ svn_error_t * error = svn_client_move5(
+ &commit_info,
+ srcPaths.array(pool),
+ destPath.cstr(),
+ force,
+ asChild,
+ makeParent,
+ map2hash(revProps,pool),
+ *m_context,
+ pool
+ );
+ if (error!=0) {
+ throw ClientException (error);
+ }
+ if (commit_info) {
+ return commit_info->revision;
+ }
+ return Revision::UNDEFINED;
+#else
+ Q_UNUSED(makeParent);
+ Q_UNUSED(revProps);
+ Revision rev;
+ if (srcPaths.size()>1 && !asChild)
+ {
+ throw ClientException("Multiple sources not allowed");
+ }
+ QString base,dir;
+ Path _dest;
+ for (size_t j=0;j<srcPaths.size();++j)
+ {
+ _dest=destPath;
+ if (asChild) {
+ srcPaths[j].split(dir,base);
+ _dest.addComponent(base);
+ }
+ rev = move(srcPaths[j],_dest,force);
+ }
+ return rev;
+#endif
+ }
+
+ svn::Revision
+ Client_impl::mkdir (const Path & path,
+ const QString& message,
+ bool makeParent,
+ const PropertiesMap&revProps
+ ) throw (ClientException)
+ {
+ Targets targets(path.path());
+ return mkdir(targets,message,makeParent,revProps);
+ }
+
+ svn::Revision
+ Client_impl::mkdir (const Targets & targets,
+ const QString&msg,
+ bool makeParent,
+ const PropertiesMap&revProps
+ ) throw (ClientException)
+ {
+ Pool pool;
+ m_context->setLogMessage(msg);
+
+ svn_commit_info_t *commit_info = NULL;
+
+ svn_error_t * error = 0;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_mkdir3
+ (&commit_info,
+ const_cast<apr_array_header_t*>(targets.array (pool)),
+ makeParent,
+ map2hash(revProps,pool),
+ *m_context, pool);
+#else
+ Q_UNUSED(makeParent);
+ Q_UNUSED(revProps);
+ error = svn_client_mkdir2
+ (&commit_info,
+ const_cast<apr_array_header_t*>(targets.array (pool)),
+ *m_context, pool);
+#endif
+
+ /* important! otherwise next op on repository uses that logmessage again! */
+ m_context->setLogMessage(QString::null);
+
+ if(error != NULL)
+ throw ClientException (error);
+ if (commit_info) {
+ return commit_info->revision;
+ }
+ return Revision::UNDEFINED;
+ }
+
+ void
+ Client_impl::cleanup (const Path & path) throw (ClientException)
+ {
+ Pool subPool;
+ apr_pool_t * apr_pool = subPool.pool ();
+
+ svn_error_t * error =
+ svn_client_cleanup (path.cstr (), *m_context, apr_pool);
+
+ if(error != NULL)
+ throw ClientException (error);
+ }
+
+ void Client_impl::resolve(const Path & path,Depth depth,const ConflictResult&resolution) throw (ClientException)
+ {
+ Pool pool;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ const svn_wc_conflict_result_t*aResult=resolution.result(pool);
+ svn_error_t*error=svn_client_resolve(path.cstr(),internal::DepthToSvn(depth),aResult->choice,*m_context,pool);
+
+#else
+ Q_UNUSED(resolution);
+ bool recurse=depth==DepthInfinity;
+ svn_error_t * error =
+ svn_client_resolved (path.cstr (),
+ recurse,
+ *m_context,
+ pool);
+#endif
+ if(error != NULL) {
+ throw ClientException (error);
+ }
+ }
+
+ svn_revnum_t
+ Client_impl::doExport (const Path & srcPath,
+ const Path & destPath,
+ const Revision & revision,
+ const Revision & peg,
+ bool overwrite,
+ const QString&native_eol,
+ bool ignore_externals,
+ svn::Depth depth) throw (ClientException)
+ {
+ Pool pool;
+ svn_revnum_t revnum = 0;
+ const char*_neol;
+ if (native_eol==QString::null) {
+ _neol = (const char*)0;
+ } else {
+ _neol = native_eol.TOUTF8();
+ }
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_error_t * error =
+ svn_client_export4(&revnum,
+ srcPath.cstr(),
+ destPath.cstr(),
+ peg.revision(),
+ revision.revision(),
+ overwrite,
+ ignore_externals,
+ internal::DepthToSvn(depth),
+ _neol,
+ *m_context,
+ pool);
+#else
+ bool recurse = depth==svn::DepthInfinity;
+ svn_error_t * error =
+ svn_client_export3(&revnum,
+ srcPath.cstr(),
+ destPath.cstr(),
+ peg.revision(),
+ revision.revision(),
+ overwrite,
+ ignore_externals,
+ recurse,
+ _neol,
+ *m_context,
+ pool);
+#endif
+ if(error != NULL)
+ throw ClientException (error);
+ return revnum;
+ }
+
+ svn_revnum_t
+ Client_impl::doSwitch (
+ const Path & path, const QString& url,
+ const Revision & revision,
+ Depth depth,
+ const Revision & peg,
+ bool sticky_depth,
+ bool ignore_externals,
+ bool allow_unversioned
+ ) throw (ClientException)
+ {
+ Pool pool;
+ svn_revnum_t revnum = 0;
+ svn_error_t * error = 0;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_switch2(
+ &revnum,
+ path.cstr(),
+ url.TOUTF8(),
+ peg.revision(),
+ revision.revision(),
+ internal::DepthToSvn(depth),
+ sticky_depth,
+ ignore_externals,
+ allow_unversioned,
+ *m_context,
+ pool
+ );
+#else
+ bool recurse = depth==DepthInfinity;
+ Q_UNUSED(peg);
+ Q_UNUSED(sticky_depth);
+ Q_UNUSED(ignore_externals);
+ Q_UNUSED(allow_unversioned);
+ error = svn_client_switch (&revnum,
+ path.cstr(),
+ url.TOUTF8(),
+ revision.revision (),
+ recurse,
+ *m_context,
+ pool);
+#endif
+ if(error != NULL) {
+ throw ClientException (error);
+ }
+ return revnum;
+ }
+
+ Revision
+ Client_impl::import (const Path & path,
+ const QString& url,
+ const QString& message,
+ svn::Depth depth,
+ bool no_ignore,bool no_unknown_nodetype,
+ const PropertiesMap&revProps
+ ) throw (ClientException)
+
+ {
+ svn_commit_info_t *commit_info = NULL;
+ Pool pool;
+
+ m_context->setLogMessage (message);
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_error_t * error =
+ svn_client_import3(&commit_info,path.cstr (),url.TOUTF8(),
+ internal::DepthToSvn(depth),no_ignore,no_unknown_nodetype,
+ map2hash(revProps,pool),
+ *m_context,pool);
+#else
+ bool recurse = depth==DepthInfinity;
+ Q_UNUSED(revProps);
+ Q_UNUSED(no_unknown_nodetype);
+
+ svn_error_t * error =
+ svn_client_import2(&commit_info,
+ path.cstr (),
+ url.TOUTF8(),
+ !recurse,
+ no_ignore,
+ *m_context,
+ pool);
+#endif
+ /* important! otherwise next op on repository uses that logmessage again! */
+ m_context->setLogMessage(QString::null);
+
+ if(error != 0) {
+ throw ClientException (error);
+ }
+ if (commit_info) {
+ return commit_info->revision;
+ }
+ return Revision::UNDEFINED;
+ }
+
+ void
+ Client_impl::relocate (const Path & path,
+ const QString& from_url,
+ const QString& to_url,
+ bool recurse) throw (ClientException)
+ {
+ Pool pool;
+ svn_error_t * error =
+ svn_client_relocate (path.cstr (),
+ from_url.TOUTF8(),
+ to_url.TOUTF8(),
+ recurse,
+ *m_context,
+ pool);
+
+ if(error != NULL)
+ throw ClientException (error);
+ }
+
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client_property.cpp b/src/svnqt/client_property.cpp
new file mode 100644
index 0000000..6438ff6
--- /dev/null
+++ b/src/svnqt/client_property.cpp
@@ -0,0 +1,450 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1200
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+// svncpp
+#include "svnqt/client_impl.hpp"
+
+// subversion api
+#include "svn_client.h"
+//#include "svn_utf.h"
+
+#include "svnqt/path.hpp"
+#include "svnqt/exception.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/revision.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include "svnqt/helper.hpp"
+
+
+namespace svn
+{
+
+ static svn_error_t* ProplistReceiver(void*baton,const char*path,apr_hash_t*prop_hash,apr_pool_t*pool)
+ {
+ Client_impl::propBaton*_baton=(Client_impl::propBaton*)baton;
+ PropertiesMap prop_map;
+ PathPropertiesMapList*mapList = (PathPropertiesMapList*)_baton->resultlist;
+
+ Context*l_context = _baton->m_context;
+ svn_client_ctx_t*ctx = l_context->ctx();
+ if (ctx&&ctx->cancel_func) {
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ }
+
+ apr_hash_index_t *hi;
+ for (hi = apr_hash_first (pool, prop_hash); hi;
+ hi = apr_hash_next (hi))
+ {
+ const void *key;
+ void *val;
+
+ apr_hash_this (hi, &key, NULL, &val);
+ prop_map[ QString::FROMUTF8( (const char *)key ) ] =
+ QString::FROMUTF8( ((const svn_string_t *)val)->data );
+ }
+ mapList->push_back(PathPropertiesMapEntry(QString::FROMUTF8(path), prop_map ));
+ return 0;
+ }
+
+ PathPropertiesMapListPtr
+ Client_impl::proplist(const Path &path,
+ const Revision &revision,
+ const Revision &peg,
+ Depth depth,
+ const StringArray&changelists)
+ {
+ Pool pool;
+
+ PathPropertiesMapListPtr path_prop_map_list = PathPropertiesMapListPtr(new PathPropertiesMapList);
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ propBaton baton;
+ baton.m_context=m_context;
+ baton.resultlist=path_prop_map_list;
+ svn_error_t * error =
+ svn_client_proplist3(
+ path.cstr (),
+ peg.revision(),
+ revision.revision (),
+ internal::DepthToSvn(depth),
+ changelists.array(pool),
+ ProplistReceiver,
+ &baton,
+ *m_context,
+ pool);
+#else
+ Q_UNUSED(changelists);
+ Q_UNUSED(ProplistReceiver);
+ bool recurse=depth==DepthInfinity;
+ apr_array_header_t * props;
+ svn_error_t * error =
+ svn_client_proplist2(&props,
+ path.cstr (),
+ peg.revision(),
+ revision.revision (),
+ recurse,
+ *m_context,
+ pool);
+
+#endif
+ if(error != NULL)
+ {
+ throw ClientException (error);
+ }
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR < 5))
+ for (int j = 0; j < props->nelts; ++j)
+ {
+ svn_client_proplist_item_t *item =
+ ((svn_client_proplist_item_t **)props->elts)[j];
+
+ PropertiesMap prop_map;
+
+ apr_hash_index_t *hi;
+ for (hi = apr_hash_first (pool, item->prop_hash); hi;
+ hi = apr_hash_next (hi))
+ {
+ const void *key;
+ void *val;
+
+ apr_hash_this (hi, &key, NULL, &val);
+ prop_map[ QString::FROMUTF8( (const char *)key ) ] =
+ QString::FROMUTF8( ((const svn_string_t *)val)->data );
+ }
+
+ path_prop_map_list->push_back( PathPropertiesMapEntry( QString::FROMUTF8(item->node_name->data), prop_map ) );
+ }
+#endif
+ return path_prop_map_list;
+ }
+
+ QPair<QLONG,PathPropertiesMapList>
+ Client_impl::propget(const QString& propName,
+ const Path &path,
+ const Revision &revision,
+ const Revision &peg,
+ Depth depth,
+ const StringArray&changelists
+ )
+ {
+ Pool pool;
+
+ apr_hash_t *props;
+ svn_revnum_t actual = svn_revnum_t(-1);
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_error_t * error = svn_client_propget3(&props,
+ propName.TOUTF8(),
+ path.cstr (),
+ peg.revision(),
+ revision.revision (),
+ &actual,
+ internal::DepthToSvn(depth),
+ changelists.array(pool),
+ *m_context,
+ pool
+ );
+#else
+ bool recurse=depth==DepthInfinity;
+ Q_UNUSED(changelists);
+ svn_error_t * error =
+ svn_client_propget2(&props,
+ propName.TOUTF8(),
+ path.cstr (),
+ peg.revision(),
+ revision.revision (),
+ recurse,
+ *m_context,
+ pool);
+#endif
+
+ if(error != NULL)
+ {
+ throw ClientException (error);
+ }
+
+ PathPropertiesMapList path_prop_map_list;
+
+
+ apr_hash_index_t *hi;
+ for (hi = apr_hash_first (pool, props); hi;
+ hi = apr_hash_next (hi))
+ {
+ PropertiesMap prop_map;
+
+ const void *key;
+ void *val;
+
+ apr_hash_this (hi, &key, NULL, &val);
+ prop_map[propName] = QString::FROMUTF8( ((const svn_string_t *)val)->data );
+ path_prop_map_list.push_back( PathPropertiesMapEntry(QString::FROMUTF8((const char *)key), prop_map ) );
+ }
+
+ return QPair<QLONG,PathPropertiesMapList>(actual,path_prop_map_list);
+ }
+
+ void
+ Client_impl::propset(const QString& propName,
+ const QString& propValue,
+ const Path &path,
+ Depth depth,
+ bool skip_checks,
+ const Revision&base_revision,
+ const StringArray&changelists,
+ const PropertiesMap&revProps
+ )
+ {
+ Pool pool;
+ const svn_string_t * propval;
+
+ if (propValue.isNull()) {
+ propval=0;
+ } else {
+ propval = svn_string_create (propValue.TOUTF8(),pool);
+ }
+
+ svn_error_t * error = 0;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_commit_info_t * commit_info;
+ svn_client_propset3(
+ &commit_info,
+ propName.TOUTF8(),
+ propval, path.cstr(),
+ internal::DepthToSvn(depth),skip_checks,
+ base_revision,
+ changelists.array(pool),
+ map2hash(revProps,pool),
+ *m_context, pool);
+
+#else
+ Q_UNUSED(changelists);
+ Q_UNUSED(base_revision);
+ Q_UNUSED(revProps);
+ bool recurse = depth==DepthInfinity;
+ svn_client_propset2(
+ propName.TOUTF8(),
+ propval, path.cstr(),
+ recurse,skip_checks, *m_context, pool);
+#endif
+ if(error != NULL) {
+ throw ClientException (error);
+ }
+ }
+
+ void
+ Client_impl::propdel(const QString& propName,
+ const Path &path,
+ Depth depth,
+ bool skip_checks,
+ const Revision&base_revision,
+ const StringArray&changelists)
+ {
+ propset(propName,QString::null,path,depth,skip_checks,base_revision,changelists);
+ }
+
+//--------------------------------------------------------------------------------
+//
+// revprop functions
+//
+//--------------------------------------------------------------------------------
+ /**
+ * lists revision properties in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param revision
+ * @param recurse
+ * @return PropertiesList
+ */
+ QPair<QLONG,PropertiesMap>
+ Client_impl::revproplist(const Path &path,
+ const Revision &revision)
+ {
+ Pool pool;
+
+ apr_hash_t * props;
+ svn_revnum_t revnum;
+ svn_error_t * error =
+ svn_client_revprop_list (&props,
+ path.cstr (),
+ revision.revision (),
+ &revnum,
+ *m_context,
+ pool);
+ if(error != NULL)
+ {
+ throw ClientException (error);
+ }
+
+ PropertiesMap prop_map;
+
+ apr_hash_index_t *hi;
+ for (hi = apr_hash_first (pool, props); hi;
+ hi = apr_hash_next (hi))
+ {
+ const void *key;
+ void *val;
+
+ apr_hash_this (hi, &key, NULL, &val);
+ prop_map[ QString::FROMUTF8( (const char *)key ) ] = QString::FROMUTF8( ((const svn_string_t *)val)->data );
+ }
+
+ return QPair<QLONG,PropertiesMap>( revnum, prop_map );
+ }
+
+ /**
+ * lists one revision property in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param revision
+ * @param recurse
+ * @return PropertiesList
+ */
+
+ QPair<QLONG,QString>
+ Client_impl::revpropget(const QString& propName,
+ const Path &path,
+ const Revision &revision)
+ {
+ Pool pool;
+
+ svn_string_t *propval;
+ svn_revnum_t revnum;
+ svn_error_t * error =
+ svn_client_revprop_get (
+ propName.TOUTF8(),
+ &propval,
+ path.cstr (),
+ revision.revision (),
+ &revnum,
+ *m_context,
+ pool);
+ if(error != NULL)
+ {
+ throw ClientException (error);
+ }
+
+ // if the property does not exist NULL is returned
+ if( propval == NULL )
+ return QPair<QLONG,QString>( 0, QString() );
+
+ return QPair<QLONG,QString>( revnum, QString::FROMUTF8(propval->data) );
+ }
+
+ /**
+ * set property in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param revision
+ * @param propName
+ * @param propValue
+ * @param recurse
+ * @param revprop
+ * @return PropertiesList
+ */
+ QLONG
+ Client_impl::revpropset(const QString& propName,
+ const QString& propValue,
+ const Path &path,
+ const Revision &revision,
+ bool force)
+ {
+ Pool pool;
+
+ const svn_string_t * propval
+ = svn_string_create (
+ propValue.TOUTF8(),
+ pool);
+
+ svn_revnum_t revnum;
+ svn_error_t * error =
+ svn_client_revprop_set (
+ propName.TOUTF8(),
+ propval,
+ path.cstr (),
+ revision.revision (),
+ &revnum,
+ force,
+ *m_context,
+ pool);
+ if(error != NULL)
+ throw ClientException (error);
+
+ return revnum;
+ }
+
+ /**
+ * delete property in @a path no matter whether local or
+ * repository
+ *
+ * @param path
+ * @param revision
+ * @param propName
+ * @param propValue
+ * @param recurse
+ * @param revprop
+ * @return PropertiesList
+ */
+ QLONG
+ Client_impl::revpropdel(const QString& propName,
+ const Path &path,
+ const Revision &revision,
+ bool force)
+ {
+ Pool pool;
+
+ svn_revnum_t revnum;
+ svn_error_t * error =
+ svn_client_revprop_set (
+ propName.TOUTF8(),
+ 0, // value = NULL
+ path.cstr (),
+ revision.revision (),
+ &revnum,
+ force,
+ *m_context,
+ pool);
+ if(error != NULL)
+ throw ClientException (error);
+
+ return revnum;
+ }
+
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/client_status.cpp b/src/svnqt/client_status.cpp
new file mode 100644
index 0000000..17f51e6
--- /dev/null
+++ b/src/svnqt/client_status.cpp
@@ -0,0 +1,736 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2008 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1200
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+
+
+// svncpp
+#include "svnqt/client_impl.hpp"
+#include "svnqt/helper.hpp"
+
+// Subversion api
+#include "svn_client.h"
+#include "svn_sorts.h"
+#include "svn_path.h"
+//#include "svn_utf.h"
+
+#include "svnqt/dirent.hpp"
+#include "svnqt/exception.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/status.hpp"
+#include "svnqt/targets.hpp"
+#include "svnqt/info_entry.hpp"
+#include "svnqt/url.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/context_listener.hpp"
+
+namespace svn
+{
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ static svn_error_t *
+ logReceiver2(
+ void*baton,
+ svn_log_entry_t *log_entry,
+ apr_pool_t * pool
+ )
+ {
+ Client_impl::sBaton * l_baton = (Client_impl::sBaton*)baton;
+ LogEntries * entries =
+ (LogEntries *) l_baton->m_data;
+ QLIST<QLONG>*rstack=
+ (QLIST<QLONG>*)l_baton->m_revstack;
+ Context*l_context = l_baton->m_context;
+ svn_client_ctx_t*ctx = l_context->ctx();
+ if (ctx&&ctx->cancel_func) {
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ }
+ if (! SVN_IS_VALID_REVNUM(log_entry->revision))
+ {
+ if (rstack&&rstack->size()>0) {
+ rstack->pop_front();
+ }
+ return SVN_NO_ERROR;
+ }
+ entries->insert (entries->begin (), LogEntry (log_entry));
+ if (rstack) {
+ entries->first().m_MergedInRevisions=(*rstack);
+ if (log_entry->has_children) {
+ rstack->push_front(log_entry->revision);
+ }
+ }
+ return SVN_NO_ERROR;
+ }
+#else
+ static svn_error_t *
+ logReceiver (
+ void *baton,
+ apr_hash_t * changedPaths,
+ svn_revnum_t rev,
+ const char *author,
+ const char *date,
+ const char *msg,
+ apr_pool_t * pool
+ )
+ {
+ Client_impl::sBaton * l_baton = (Client_impl::sBaton*)baton;
+ LogEntries * entries =
+ (LogEntries *) l_baton->m_data;
+
+ /* check every loop for cancel of operation */
+ Context*l_context = l_baton->m_context;
+ svn_client_ctx_t*ctx = l_context->ctx();
+ if (ctx&&ctx->cancel_func) {
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ }
+ entries->insert (entries->begin (), LogEntry (rev, author, date, msg));
+ if (changedPaths != NULL)
+ {
+ LogEntry &entry = entries->front ();
+
+ for (apr_hash_index_t *hi = apr_hash_first (pool, changedPaths);
+ hi != NULL;
+ hi = apr_hash_next (hi))
+ {
+ const void *pv;
+ void *val;
+ apr_hash_this (hi, &pv, NULL, &val);
+
+ svn_log_changed_path_t *log_item = reinterpret_cast<svn_log_changed_path_t *> (val);
+ const char* path = reinterpret_cast<const char*>(pv);
+
+ entry.changedPaths.push_back (
+ LogChangePathEntry (path,
+ log_item->action,
+ log_item->copyfrom_path,
+ log_item->copyfrom_rev) );
+
+ }
+ }
+
+ return SVN_NO_ERROR;
+ }
+#endif
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ static svn_error_t *
+ logMapReceiver2(
+ void*baton,
+ svn_log_entry_t *log_entry,
+ apr_pool_t * pool
+ )
+ {
+ Client_impl::sBaton * l_baton = (Client_impl::sBaton*)baton;
+ LogEntriesMap * entries =
+ (LogEntriesMap *) l_baton->m_data;
+ Context*l_context = l_baton->m_context;
+ QLIST<QLONG>*rstack=
+ (QLIST<QLONG>*)l_baton->m_revstack;
+ svn_client_ctx_t*ctx = l_context->ctx();
+ if (ctx&&ctx->cancel_func) {
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ }
+ if (! SVN_IS_VALID_REVNUM(log_entry->revision))
+ {
+ if (rstack&&rstack->size()>0) {
+ rstack->pop_front();
+ }
+ return SVN_NO_ERROR;
+ }
+ (*entries)[log_entry->revision]=LogEntry (log_entry);
+ /// @TODO insert it into last logentry
+ if (rstack) {
+ (*entries)[log_entry->revision].m_MergedInRevisions=(*rstack);
+ if (log_entry->has_children) {
+ rstack->push_front(log_entry->revision);
+ }
+ }
+ return SVN_NO_ERROR;
+ }
+#else
+ static svn_error_t *
+ logMapReceiver (void *baton,
+ apr_hash_t * changedPaths,
+ svn_revnum_t rev,
+ const char *author,
+ const char *date,
+ const char *msg,
+ apr_pool_t * pool
+ )
+ {
+ Client_impl::sBaton * l_baton = (Client_impl::sBaton*)baton;
+ LogEntriesMap * entries =
+ (LogEntriesMap *) l_baton->m_data;
+
+ /* check every loop for cancel of operation */
+ Context*l_context = l_baton->m_context;
+ svn_client_ctx_t*ctx = l_context->ctx();
+ if (ctx&&ctx->cancel_func) {
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ }
+ (*entries)[rev]=LogEntry(rev, author, date, msg);
+ if (changedPaths != NULL)
+ {
+ LogEntry &entry = (*entries)[rev];
+
+ for (apr_hash_index_t *hi = apr_hash_first (pool, changedPaths);
+ hi != NULL;
+ hi = apr_hash_next (hi))
+ {
+ const void *pv;
+ void *val;
+ apr_hash_this (hi, &pv, NULL, &val);
+
+ svn_log_changed_path_t *log_item = reinterpret_cast<svn_log_changed_path_t *> (val);
+ const char* path = reinterpret_cast<const char*>(pv);
+
+ entry.changedPaths.push_back (
+ LogChangePathEntry (path,
+ log_item->action,
+ log_item->copyfrom_path,
+ log_item->copyfrom_rev) );
+
+ }
+ }
+
+ return NULL;
+ }
+#endif
+
+ struct StatusEntriesBaton {
+ apr_pool_t* pool;
+ apr_hash_t* hash;
+ Context*m_Context;
+ StatusEntriesBaton() {
+ pool = 0;
+ hash = 0;
+ m_Context = 0;
+ }
+ };
+
+ static svn_error_t * InfoEntryFunc(void*baton,
+ const char*path,
+ const svn_info_t*info,
+ apr_pool_t *)
+ {
+ StatusEntriesBaton* seb = (StatusEntriesBaton*)baton;
+ if (seb->m_Context) {
+ /* check every loop for cancel of operation */
+ Context*l_context = seb->m_Context;
+ svn_client_ctx_t*ctx = l_context->ctx();
+ if (ctx&&ctx->cancel_func) {
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ }
+ }
+ path = apr_pstrdup (seb->pool, path);
+ InfoEntry*e = new InfoEntry(info,path);
+ apr_hash_set (seb->hash, path, APR_HASH_KEY_STRING, e);
+ return NULL;
+ }
+
+ static void StatusEntriesFunc (void *baton,
+ const char *path,
+ svn_wc_status2_t *status)
+ {
+ svn_wc_status2_t* stat;
+ StatusEntriesBaton* seb = (StatusEntriesBaton*)baton;
+
+ path = apr_pstrdup (seb->pool, path);
+ stat = svn_wc_dup_status2 (status, seb->pool);
+ apr_hash_set (seb->hash, path, APR_HASH_KEY_STRING, stat);
+ }
+
+ static StatusEntries
+ localStatus (const Path& path,
+ Depth depth,
+ const bool get_all,
+ const bool update,
+ const bool no_ignore,
+ const bool hide_externals,
+ const StringArray & changelists,
+ Context * context)
+ {
+ svn_error_t *error;
+ StatusEntries entries;
+ apr_hash_t *status_hash;
+ svn_revnum_t revnum;
+ Revision rev (Revision::HEAD);
+ Pool pool;
+ StatusEntriesBaton baton;
+
+ status_hash = apr_hash_make (pool);
+ baton.hash = status_hash;
+ baton.pool = pool;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_status3 (
+ &revnum, // revnum
+ path.path().TOUTF8(), // path
+ rev,
+ StatusEntriesFunc, // status func
+ &baton, // status baton
+ internal::DepthToSvn(depth), // see svn::Depth
+ get_all, // get all not only interesting
+ update, // check for updates
+ no_ignore, // hide ignored files or not
+ hide_externals, // hide external
+ changelists.array(pool),
+ *context, //client ctx
+ pool);
+#else
+ Q_UNUSED(changelists);
+ error = svn_client_status2 (
+ &revnum, // revnum
+ path.path().TOUTF8(), // path
+ rev,
+ StatusEntriesFunc, // status func
+ &baton, // status baton
+ (depth==DepthInfinity), //recurse
+ get_all, // get all not only interesting
+ update, // check for updates
+ no_ignore, // hide ignored files or not
+ hide_externals, // hide external
+ *context, //client ctx
+ pool);
+#endif
+
+ if (error!=NULL)
+ {
+ throw ClientException (error);
+ }
+
+ apr_array_header_t *statusarray =
+ svn_sort__hash (status_hash, svn_sort_compare_items_as_paths,
+ pool);
+ int i;
+
+ /* Loop over array, printing each name/status-structure */
+ for (i = 0; i < statusarray->nelts; ++i)
+ {
+ const svn_sort__item_t *item;
+ const char *filePath;
+ svn_wc_status2_t *status = NULL;
+
+ item = &APR_ARRAY_IDX (statusarray, i, const svn_sort__item_t);
+ status = (svn_wc_status2_t *) item->value;
+
+ filePath = (const char *) item->key;
+ entries.push_back (StatusPtr(new Status(filePath, status)));
+ }
+ return entries;
+ }
+
+ static StatusPtr
+ dirEntryToStatus (const Path& path, DirEntryPtr dirEntry)
+ {
+ QString url = path.path();
+ url += QString::FROMUTF8("/");
+ url += dirEntry->name();
+ return StatusPtr(new Status (url, dirEntry));
+ }
+
+ static StatusPtr
+ infoEntryToStatus(const Path&,const InfoEntry&infoEntry)
+ {
+ return StatusPtr(new Status(infoEntry.url(),infoEntry));
+ }
+
+ static StatusEntries
+ remoteStatus (Client * client,
+ const Path& path,
+ Depth depth,
+ const bool ,
+ const bool ,
+ const bool ,
+ const Revision revision,
+ Context * ,
+ bool detailed_remote)
+ {
+ DirEntries dirEntries = client->list(path, revision, revision, depth,detailed_remote);
+ DirEntries::const_iterator it;
+
+ StatusEntries entries;
+ QString url = path.path();
+ url+=QString::FROMUTF8("/");
+
+ for (it = dirEntries.begin (); it != dirEntries.end (); it++)
+ {
+ DirEntryPtr dirEntry = *it;
+ if (dirEntry->name().isEmpty())
+ continue;
+ entries.push_back(dirEntryToStatus (path, dirEntry));
+ }
+ return entries;
+ }
+
+ StatusEntries
+ Client_impl::status (const Path& path,
+ Depth depth,
+ const bool get_all,
+ const bool update,
+ const bool no_ignore,
+ const Revision revision,
+ bool detailed_remote,
+ const bool hide_externals,
+ const StringArray & changelists) throw (ClientException)
+ {
+ if (Url::isValid (path.path())) {
+ return remoteStatus (this, path, depth, get_all, update,
+ no_ignore,revision,m_context,detailed_remote);
+ } else {
+ return localStatus (path, depth, get_all, update,
+ no_ignore, hide_externals,changelists, m_context);
+ }
+ }
+
+ static StatusPtr
+ localSingleStatus (const Path& path, Context * context,bool update=false)
+ {
+ svn_error_t *error;
+ apr_hash_t *status_hash;
+ Pool pool;
+ StatusEntriesBaton baton;
+ svn_revnum_t revnum;
+ Revision rev (Revision::HEAD);
+
+ status_hash = apr_hash_make( pool );
+ baton.hash = status_hash;
+ baton.pool = pool;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_status3 (
+ &revnum, // revnum
+ path.path().TOUTF8(), // path
+ rev,
+ StatusEntriesFunc, // status func
+ &baton, // status baton
+ svn_depth_empty, // not recurse
+ true, // get all not only interesting
+ update, // check for updates
+ false, // hide ignored files or not
+ false, // hide external
+ 0,
+ *context, //client ctx
+ pool);
+#else
+ error = svn_client_status2 (
+ &revnum, // revnum
+ path.path().TOUTF8(), // path
+ rev,
+ StatusEntriesFunc, // status func
+ &baton, // status baton
+ false,
+ true,
+ update,
+ false,
+ false,
+ *context, //client ctx
+ pool);
+#endif
+ if (error != NULL)
+ {
+ throw ClientException (error);
+ }
+
+ apr_array_header_t *statusarray =
+ svn_sort__hash (status_hash, svn_sort_compare_items_as_paths,
+ pool);
+ const svn_sort__item_t *item;
+ const char *filePath;
+ svn_wc_status2_t *status = NULL;
+
+ item = &APR_ARRAY_IDX (statusarray, 0, const svn_sort__item_t);
+ status = (svn_wc_status2_t *) item->value;
+ filePath = (const char *) item->key;
+
+ return StatusPtr(new Status (filePath, status));
+ };
+
+ static StatusPtr
+ remoteSingleStatus (Client * client, const Path& path,const Revision revision, Context * )
+ {
+ InfoEntries infoEntries = client->info(path,DepthEmpty,revision,Revision(Revision::UNDEFINED));
+ if (infoEntries.size () == 0)
+ return StatusPtr(new Status());
+ else
+ return infoEntryToStatus (path, infoEntries [0]);
+ }
+
+ StatusPtr
+ Client_impl::singleStatus (const Path& path,bool update,const Revision revision) throw (ClientException)
+ {
+ if (Url::isValid (path.path()))
+ return remoteSingleStatus (this, path,revision, m_context);
+ else
+ return localSingleStatus (path, m_context,update);
+ }
+
+ bool
+ Client_impl::log (const Path& path, const Revision & revisionStart,
+ const Revision & revisionEnd,
+ LogEntriesMap&log_target,
+ const Revision & revisionPeg,
+ bool discoverChangedPaths,
+ bool strictNodeHistory,int limit,
+ bool include_merged_revisions,
+ const StringArray&revprops
+ ) throw (ClientException)
+ {
+ Targets target(path);
+ Pool pool;
+ sBaton l_baton;
+ QLIST<QLONG> revstack;
+ l_baton.m_context=m_context;
+ l_baton.m_data = &log_target;
+ l_baton.m_revstack = &revstack;
+ svn_error_t *error;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_log4 (
+ target.array (pool),
+ revisionPeg.revision(),
+ revisionStart.revision (),
+ revisionEnd.revision (),
+ limit,
+ discoverChangedPaths ? 1 : 0,
+ strictNodeHistory ? 1 : 0,
+ include_merged_revisions?1:0,
+ revprops.array(pool),
+ logMapReceiver2,
+ &l_baton,
+ *m_context, // client ctx
+ pool);
+#elif ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ Q_UNUSED(include_merged_revisions);
+ Q_UNUSED(revprops);
+
+ error = svn_client_log3 (
+ target.array (pool),
+ revisionPeg.revision(),
+ revisionStart.revision (),
+ revisionEnd.revision (),
+ limit,
+ discoverChangedPaths ? 1 : 0,
+ strictNodeHistory ? 1 : 0,
+ logMapReceiver,
+ &l_baton,
+ *m_context, // client ctx
+ pool);
+#else
+ Q_UNUSED(include_merged_revisions);
+ Q_UNUSED(revprops);
+ Q_UNUSED(revisionPeg);
+
+ error = svn_client_log2 (
+ target.array (pool),
+ revisionStart.revision (),
+ revisionEnd.revision (),
+ limit,
+ discoverChangedPaths ? 1 : 0,
+ strictNodeHistory ? 1 : 0,
+ logMapReceiver,
+ &l_baton,
+ *m_context, // client ctx
+ pool);
+#endif
+ if (error != NULL)
+ {
+ throw ClientException (error);
+ }
+ return true;
+ }
+
+ LogEntriesPtr
+ Client_impl::log (const Path& path, const Revision & revisionStart,
+ const Revision & revisionEnd, const Revision & revisionPeg,
+ bool discoverChangedPaths,
+ bool strictNodeHistory,int limit,
+ bool include_merged_revisions,
+ const StringArray&revprops
+ ) throw (ClientException)
+ {
+ Targets target(path);
+ Pool pool;
+ LogEntriesPtr entries = LogEntriesPtr(new LogEntries ());
+ QLIST<QLONG> revstack;
+ sBaton l_baton;
+ l_baton.m_context=m_context;
+ l_baton.m_data = entries;
+ l_baton.m_revstack = &revstack;
+
+ svn_error_t *error;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error = svn_client_log4 (
+ target.array (pool),
+ revisionPeg.revision(),
+ revisionStart.revision (),
+ revisionEnd.revision (),
+ limit,
+ discoverChangedPaths ? 1 : 0,
+ strictNodeHistory ? 1 : 0,
+ include_merged_revisions?1:0,
+ revprops.array(pool),
+ logReceiver2,
+ &l_baton,
+ *m_context, // client ctx
+ pool);
+#elif ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ Q_UNUSED(include_merged_revisions);
+ Q_UNUSED(revprops);
+
+ error = svn_client_log3 (
+ target.array (pool),
+ revisionPeg.revision(),
+ revisionStart.revision (),
+ revisionEnd.revision (),
+ limit,
+ discoverChangedPaths ? 1 : 0,
+ strictNodeHistory ? 1 : 0,
+ logReceiver,
+ &l_baton,
+ *m_context, // client ctx
+ pool);
+#else
+ Q_UNUSED(include_merged_revisions);
+ Q_UNUSED(revprops);
+ Q_UNUSED(revisionPeg);
+
+ error = svn_client_log2 (
+ target.array (pool),
+ revisionStart.revision (),
+ revisionEnd.revision (),
+ limit,
+ discoverChangedPaths ? 1 : 0,
+ strictNodeHistory ? 1 : 0,
+ logReceiver,
+ &l_baton,
+ *m_context, // client ctx
+ pool);
+#endif
+ if (error != NULL)
+ {
+ throw ClientException (error);
+ }
+
+ return entries;
+ }
+
+ InfoEntries
+ Client_impl::info(const Path& _p,
+ Depth depth,
+ const Revision & rev,
+ const Revision & peg_revision,
+ const StringArray&changelists
+ ) throw (ClientException)
+ {
+
+ InfoEntries ientries;
+ Pool pool;
+ svn_error_t *error = NULL;
+ StatusEntriesBaton baton;
+ apr_hash_t *status_hash;
+
+ status_hash = apr_hash_make (pool);
+ baton.hash = status_hash;
+ baton.pool = pool;
+ baton.m_Context=m_context;
+ svn_opt_revision_t pegr;
+ const char *truepath = 0;
+ bool internal_peg = false;
+ QByteArray _buf = _p.cstr();
+
+ error = svn_opt_parse_path(&pegr, &truepath,
+ _buf,
+ pool);
+ if (error != NULL)
+ throw ClientException (error);
+
+ if (peg_revision.kind() == svn_opt_revision_unspecified) {
+ if ((svn_path_is_url (_p.cstr())) && (pegr.kind == svn_opt_revision_unspecified)) {
+ pegr.kind = svn_opt_revision_head;
+ internal_peg=true;
+ }
+ }
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ error =
+ svn_client_info2(truepath,
+ internal_peg?&pegr:peg_revision.revision(),
+ rev.revision (),
+ &InfoEntryFunc,
+ &baton,
+ internal::DepthToSvn(depth),
+ changelists.array(pool),
+ *m_context, //client ctx
+ pool);
+#else
+ bool rec = depth==DepthInfinity;
+ Q_UNUSED(changelists);
+ error =
+ svn_client_info(truepath,
+ internal_peg?&pegr:peg_revision.revision(),
+ rev.revision (),
+ &InfoEntryFunc,
+ &baton,
+ rec,
+ *m_context, //client ctx
+ pool);
+#endif
+
+ if (error != NULL)
+ throw ClientException (error);
+
+ apr_array_header_t *statusarray =
+ svn_sort__hash (status_hash, svn_sort_compare_items_as_paths,
+ pool);
+ int i;
+
+ /* Loop over array, printing each name/status-structure */
+ for (i=0; i< statusarray->nelts; ++i)
+ {
+ const svn_sort__item_t *item;
+ InfoEntry*e = NULL;
+ item = &APR_ARRAY_IDX (statusarray, i, const svn_sort__item_t);
+ e = (InfoEntry *) item->value;
+ ientries.push_back(*e);
+ delete e;
+ }
+ if (error != NULL)
+ throw ClientException (error);
+ return ientries;
+ }
+
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/cmakemodules/FindSqlite.cmake b/src/svnqt/cmakemodules/FindSqlite.cmake
new file mode 100644
index 0000000..3c50d33
--- /dev/null
+++ b/src/svnqt/cmakemodules/FindSqlite.cmake
@@ -0,0 +1,32 @@
+IF (SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES)
+ SET(SQLITE_FOUND TRUE)
+ELSE (SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES)
+ INCLUDE(UsePkgConfig)
+ PKGCONFIG(sqlite3 _sqliteincdir _sqlitelibdir _sqlitelinkflags _sqlitecflags)
+
+ FIND_PATH(SQLITE_INCLUDE_DIR sqlite3.h
+ ${_sqliteincdir}
+ /usr/include
+ /usr/local/include
+ )
+ FIND_LIBRARY(SQLITE_LIBRARIES NAMES sqlite3
+ PATHS
+ ${_sqlitelibdir}
+ /usr/lib
+ /usr/local/lib
+ )
+
+ IF (SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES)
+ SET(SQLITE_FOUND TRUE)
+ ENDIF (SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES)
+
+ IF (SQLITE_FOUND)
+ MESSAGE(STATUS "Found sqlite3: ${SQLITE_LIBRARIES}")
+ ELSE (SQLITE_FOUND)
+ MESSAGE(STATUS "Could not find sqlite3")
+ ADD_DEFINITIONS(-DNO_SQLITE3)
+ ENDIF (SQLITE_FOUND)
+
+ MARK_AS_ADVANCED(SQLITE_LIBRARIES SQLITE_INCLUDE_DIR)
+
+ENDIF (SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES)
diff --git a/src/svnqt/cmakemodules/FindSubversion.cmake b/src/svnqt/cmakemodules/FindSubversion.cmake
new file mode 100644
index 0000000..358ee3a
--- /dev/null
+++ b/src/svnqt/cmakemodules/FindSubversion.cmake
@@ -0,0 +1,352 @@
+SET(SUBVERSIONFOUND)
+SET(SUBVERSION_ALL_LIBS)
+
+INCLUDE (CheckIncludeFiles)
+
+#search libraries for UNIX
+IF (UNIX)
+
+ MACRO(FIND_SUB_LIB targetvar libname)
+ IF (SUBVERSION_INSTALL_PATH)
+ FIND_LIBRARY(${targetvar} ${libname}
+ PATHS
+ ${SUBVERSION_INSTALL_PATH}/lib
+ NO_DEFAULT_PATH
+ )
+ ENDIF(SUBVERSION_INSTALL_PATH)
+ FIND_LIBRARY(${targetvar} ${libname}
+ PATHS
+ /usr/lib
+ /usr/local/lib
+ )
+ ENDMACRO(FIND_SUB_LIB)
+
+ IF (SUBVERSION_INSTALL_PATH)
+ FIND_PATH(SUBVERSION_INCLUDE_DIR svn_client.h
+ PATHS
+ ${SUBVERSION_INSTALL_PATH}/include/subversion-1
+ NO_DEFAULT_PATH
+ )
+ ENDIF (SUBVERSION_INSTALL_PATH)
+ FIND_PATH(SUBVERSION_INCLUDE_DIR svn_client.h
+ /usr/include/subversion-1
+ /usr/local/include/subversion-1)
+
+ FIND_SUB_LIB(SUBVERSION_CLIENTLIB svn_client-1)
+ FIND_SUB_LIB(SUBVERSION_REPOSITORYLIB svn_repos-1)
+ FIND_SUB_LIB(SUBVERSION_WCLIB svn_wc-1)
+ FIND_SUB_LIB(SUBVERSION_FSLIB svn_fs-1)
+ FIND_SUB_LIB(SUBVERSION_SUBRLIB svn_subr-1)
+ FIND_SUB_LIB(SUBVERSION_RALIB svn_ra-1)
+ FIND_SUB_LIB(SUBVERSION_DIFFLIB svn_diff-1)
+
+ FIND_PROGRAM(APR_CONFIG NAMES apr-config apr-1-config
+ PATHS
+ /usr/local/apr/bin
+ )
+
+ FIND_PROGRAM(APU_CONFIG NAMES apu-config apu-1-config
+ PATHS
+ /usr/local/apr/bin
+ )
+
+ if(NOT APR_CONFIG)
+ MESSAGE(SEND_ERROR "Error: no apr-config found")
+ endif(NOT APR_CONFIG)
+
+ if(NOT APU_CONFIG)
+ MESSAGE(SEND_ERROR "Error: no apu-config found")
+ endif(NOT APU_CONFIG)
+
+ EXEC_PROGRAM(${APR_CONFIG} ARGS "--includedir" OUTPUT_VARIABLE APR_INCLUDE_DIR)
+ EXEC_PROGRAM(${APU_CONFIG} ARGS "--includedir" OUTPUT_VARIABLE APU_INCLUDE_DIR)
+
+ EXEC_PROGRAM(${APR_CONFIG} ARGS "--cppflags" OUTPUT_VARIABLE APR_CPP_FLAGS)
+ EXEC_PROGRAM(${APU_CONFIG} ARGS "--cppflags" OUTPUT_VARIABLE APU_CPP_FLAGS)
+
+ EXEC_PROGRAM(${APR_CONFIG} ARGS "--ldflags --libs --link-ld" OUTPUT_VARIABLE APR_EXTRA_LIBFLAGS)
+ EXEC_PROGRAM(${APU_CONFIG} ARGS "--ldflags --libs --link-ld" OUTPUT_VARIABLE APU_EXTRA_LIBFLAGS)
+
+ CHECK_INCLUDE_FILES(execinfo.h HAS_BACKTRACE_H)
+
+ENDIF (UNIX)
+
+#search libaries for Windows
+IF (WIN32)
+
+ # search for pathes
+ FIND_PATH (SUBVERSION_BIN_DIR svn.exe
+ "$ENV{ProgramFiles}/Subversion/bin"
+ )
+
+ FIND_PATH (SUBVERSION_INCLUDE_DIR svn_client.h
+ "$ENV{ProgramFiles}/Subversion/include"
+ )
+
+ FIND_PATH(APR_INCLUDE_DIR apr.h
+ "$ENV{ProgramFiles}/Subversion/include/apr"
+ )
+
+ FIND_PATH(APU_INCLUDE_DIR apu.h
+ "$ENV{ProgramFiles}/Subversion/include/apr-util"
+ )
+
+ # search for libraries
+ FIND_LIBRARY(APR_LIB libapr
+ "$ENV{ProgramFiles}/Subversion/lib/apr"
+ )
+
+ FIND_LIBRARY(APRICONV_LIB libapriconv
+ "$ENV{ProgramFiles}/Subversion/lib/apr-iconv"
+ )
+
+ FIND_LIBRARY(APU_LIB libaprutil
+ "$ENV{ProgramFiles}/Subversion/lib/apr-util"
+ )
+
+ FIND_LIBRARY(APU_XMLLIB xml
+ "$ENV{ProgramFiles}/Subversion/lib/apr-util"
+ )
+
+ FIND_LIBRARY(NEON_LIB libneon
+ "$ENV{ProgramFiles}/Subversion/lib/neon"
+ )
+
+ FIND_LIBRARY(NEON_ZLIBSTATLIB zlibstat
+ "$ENV{ProgramFiles}/Subversion/lib/neon"
+ )
+
+ FIND_LIBRARY(INTL3LIB intl3_svn
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(DB44_LIB libdb44
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_CLIENTLIB libsvn_client-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_DELTALIB libsvn_delta-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_DIFFLIB libsvn_diff-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_FSBASELIB libsvn_fs_base-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_FSFSLIB libsvn_fs_fs-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_FSUTILLIB libsvn_fs_util-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_FSLIB libsvn_fs-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_RALOCALLIB libsvn_ra_local-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_RANEONLIB libsvn_ra_neon-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_RASVNLIB libsvn_ra_svn-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_RALIB libsvn_ra-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_REPOSITORYLIB libsvn_repos-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_SUBRLIB libsvn_subr-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ FIND_LIBRARY(SUBVERSION_WCLIB libsvn_wc-1
+ "$ENV{ProgramFiles}/Subversion/lib"
+ )
+
+ SET(APR_EXTRA_LIBFLAGS )
+ SET(APU_EXTRA_LIBFLAGS )
+
+
+ # check found libraries
+ if (NOT APR_LIB)
+ MESSAGE(SEND_ERROR "No apr lib found!")
+ ELSE (NOT APR_LIB)
+ MESSAGE(STATUS "Found apr lib: ${APR_LIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${APR_LIB})
+ endif(NOT APR_LIB)
+
+ if (NOT APRICONV_LIB)
+ MESSAGE(SEND_ERROR "No apriconv lib found!")
+ ELSE (NOT APRICONV_LIB)
+ MESSAGE(STATUS "Found apriconv lib: ${APRICONV_LIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${APRICONV_LIB})
+ endif(NOT APRICONV_LIB)
+
+ if (NOT APU_LIB)
+ MESSAGE(SEND_ERROR "No aprutil lib found!")
+ ELSE (NOT APU_LIB)
+ MESSAGE(STATUS "Found aprutil lib: ${APU_LIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${APU_LIB})
+ endif(NOT APU_LIB)
+
+ if (NOT APU_XMLLIB)
+ MESSAGE(SEND_ERROR "No xml lib found!")
+ ELSE (NOT APU_XMLLIB)
+ MESSAGE(STATUS "Found xml lib: ${APU_XMLLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${APU_XMLLIB})
+ endif(NOT APU_XMLLIB)
+
+ if (NOT NEON_LIB)
+ MESSAGE(SEND_ERROR "No neon lib found!")
+ ELSE (NOT NEON_LIB)
+ MESSAGE(STATUS "Found neon lib: ${NEON_LIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${NEON_LIB})
+ endif(NOT NEON_LIB)
+
+ if (NOT NEON_ZLIBSTATLIB)
+ MESSAGE(SEND_ERROR "No zlibstat lib found!")
+ ELSE (NOT APRICONV_LIB)
+ MESSAGE(STATUS "Found zlibstat lib: ${NEON_ZLIBSTATLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${NEON_ZLIBSTATLIB})
+ endif(NOT NEON_ZLIBSTATLIB)
+
+ if (NOT INTL3LIB)
+ MESSAGE(SEND_ERROR "No intl3 lib found!")
+ ELSE (NOT INTL3LIB)
+ MESSAGE(STATUS "Found intl3 lib: ${INTL3LIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${INTL3LIB})
+ endif(NOT INTL3LIB)
+
+ if (NOT DB44_LIB)
+ MESSAGE(SEND_ERROR "No db44 lib found!")
+ ELSE (NOT DB44_LIB)
+ MESSAGE(STATUS "Found db44 lib: ${DB44_LIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${DB44_LIB})
+ endif(NOT DB44_LIB)
+
+ if (NOT SUBVERSION_DELTALIB)
+ MESSAGE(SEND_ERROR "No subversion delta lib found!")
+ ELSE (NOT SUBVERSION_DELTALIB)
+ MESSAGE(STATUS "Found subversion delta lib: ${SUBVERSION_DELTALIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_DELTALIB})
+ endif(NOT SUBVERSION_DELTALIB)
+
+ if (NOT SUBVERSION_FSBASELIB)
+ MESSAGE(SEND_ERROR "No subversion fs base lib found!")
+ ELSE (NOT SUBVERSION_FSBASELIB)
+ MESSAGE(STATUS "Found subversion fs base lib: ${SUBVERSION_FSBASELIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_FSBASELIB})
+ endif(NOT SUBVERSION_FSBASELIB)
+
+ if (NOT SUBVERSION_FSFSLIB)
+ MESSAGE(SEND_ERROR "No subversion fs fs lib found!")
+ ELSE (NOT SUBVERSION_FSFSLIB)
+ MESSAGE(STATUS "Found subversion fs fs lib: ${SUBVERSION_FSFSLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_FSFSLIB})
+ endif(NOT SUBVERSION_FSFSLIB)
+
+ if (NOT SUBVERSION_FSUTILLIB)
+ MESSAGE(SEND_ERROR "No subversion fs util lib found!")
+ ELSE (NOT SUBVERSION_FSUTILLIB)
+ MESSAGE(STATUS "Found subversion fs util lib: ${SUBVERSION_FSUTILLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_FSUTILLIB})
+ endif(NOT SUBVERSION_FSUTILLIB)
+
+ if (NOT SUBVERSION_RALOCALLIB)
+ MESSAGE(SEND_ERROR "No subversion ra local lib found!")
+ ELSE (NOT SUBVERSION_RALOCALLIB)
+ MESSAGE(STATUS "Found subversion ra local lib: ${SUBVERSION_RALOCALLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_RALOCALLIB})
+ endif(NOT SUBVERSION_RALOCALLIB)
+
+ if (NOT SUBVERSION_RANEONLIB)
+ MESSAGE(SEND_ERROR "No subversion ra neon lib found!")
+ ELSE (NOT SUBVERSION_RANEONLIB)
+ MESSAGE(STATUS "Found subversion ra neon lib: ${SUBVERSION_RANEONLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_RANEONLIB})
+ endif(NOT SUBVERSION_RANEONLIB)
+
+ if (NOT SUBVERSION_RASVNLIB)
+ MESSAGE(SEND_ERROR "No subversion ra svn lib found!")
+ ELSE (NOT SUBVERSION_RASVNLIB)
+ MESSAGE(STATUS "Found subversion ra svn lib: ${SUBVERSION_RASVNLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_RASVNLIB})
+ endif(NOT SUBVERSION_RASVNLIB)
+
+ENDIF (WIN32)
+
+
+IF(NOT SUBVERSION_INCLUDE_DIR)
+ MESSAGE(SEND_ERROR "No subversion includes found!")
+ELSE(NOT SUBVERSION_INCLUDE_DIR)
+ MESSAGE(STATUS "Found subversion include: ${SUBVERSION_INCLUDE_DIR}")
+ENDIF(NOT SUBVERSION_INCLUDE_DIR)
+
+if (NOT SUBVERSION_CLIENTLIB)
+ MESSAGE(SEND_ERROR "No subversion client libs found!")
+ELSE (NOT SUBVERSION_CLIENTLIB)
+ MESSAGE(STATUS "Found subversion client lib: ${SUBVERSION_CLIENTLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_CLIENTLIB})
+endif(NOT SUBVERSION_CLIENTLIB)
+
+if (NOT SUBVERSION_DIFFLIB)
+ MESSAGE(SEND_ERROR "No subversion diff lib found!")
+ELSE (NOT SUBVERSION_DIFFLIB)
+ MESSAGE(STATUS "Found subversion diff lib: ${SUBVERSION_DIFFLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_DIFFLIB})
+endif(NOT SUBVERSION_DIFFLIB)
+
+if (NOT SUBVERSION_FSLIB)
+ MESSAGE(SEND_ERROR "No subversion fs lib found!")
+ELSE (NOT SUBVERSION_FSLIB)
+ MESSAGE(STATUS "Found subversion fs lib: ${SUBVERSION_FSLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_FSLIB})
+endif(NOT SUBVERSION_FSLIB)
+
+if (NOT SUBVERSION_RALIB)
+ MESSAGE(SEND_ERROR "No subversion ra lib found!")
+ELSE (NOT SUBVERSION_RALIB)
+ MESSAGE(STATUS "Found subversion ra lib: ${SUBVERSION_RALIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_RALIB})
+endif(NOT SUBVERSION_RALIB)
+
+if (NOT SUBVERSION_REPOSITORYLIB)
+ MESSAGE(SEND_ERROR "No subversion repository lib found!")
+ELSE (NOT SUBVERSION_REPOSITORYLIB)
+ MESSAGE(STATUS "Found subversion repository lib: ${SUBVERSION_REPOSITORYLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_REPOSITORYLIB})
+endif(NOT SUBVERSION_REPOSITORYLIB)
+
+if (NOT SUBVERSION_SUBRLIB)
+ MESSAGE(SEND_ERROR "No subversion subr lib found!")
+ELSE (NOT SUBVERSION_SUBRLIB)
+ MESSAGE(STATUS "Found subversion subr lib: ${SUBVERSION_SUBRLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_SUBRLIB})
+endif(NOT SUBVERSION_SUBRLIB)
+
+if (NOT SUBVERSION_WCLIB)
+ MESSAGE(SEND_ERROR "No subversion wc lib found!")
+ELSE (NOT SUBVERSION_WCLIB)
+ MESSAGE(STATUS "Found subversion wc lib: ${SUBVERSION_WCLIB}")
+ SET(SUBVERSION_ALL_LIBS ${SUBVERSION_ALL_LIBS} ${SUBVERSION_WCLIB})
+endif(NOT SUBVERSION_WCLIB)
+
+
+SET(SUBVERSIONFOUND true)
diff --git a/src/svnqt/commititem.cpp b/src/svnqt/commititem.cpp
new file mode 100644
index 0000000..2d97e6c
--- /dev/null
+++ b/src/svnqt/commititem.cpp
@@ -0,0 +1,167 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "commititem.hpp"
+
+#include <svn_client.h>
+#include <svn_props.h>
+
+namespace svn {
+
+CommitItem::CommitItem(const svn_client_commit_item_t*_item)
+{
+ init();
+ if (_item) {
+ m_Path = QString::FROMUTF8(_item->path);
+ m_Kind = _item->kind;
+ m_Url = QString::FROMUTF8(_item->url);
+ if (_item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY) {
+ m_CopyFromRevision = _item->revision;
+ } else {
+ m_Revision = _item->revision;
+ }
+ m_CopyFromUrl = QString::FROMUTF8(_item->copyfrom_url);
+ m_State = _item->state_flags;
+ convertprop(_item->wcprop_changes);
+ }
+}
+
+CommitItem::CommitItem(const svn_client_commit_item2_t*_item)
+{
+ init();
+
+ if (_item) {
+ m_Path = QString::FROMUTF8(_item->path);
+ m_Kind = _item->kind;
+ m_Url = QString::FROMUTF8(_item->url);
+ m_Revision = _item->revision;
+ m_CopyFromRevision = _item->copyfrom_rev;
+ m_CopyFromUrl = QString::FROMUTF8(_item->copyfrom_url);
+ m_State = _item->state_flags;
+ convertprop(_item->wcprop_changes);
+ }
+}
+
+CommitItem::CommitItem(const svn_client_commit_item3_t*_item)
+{
+ init();
+
+ if (_item) {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ m_Path = QString::FROMUTF8(_item->path);
+ m_Kind = _item->kind;
+ m_Url = QString::FROMUTF8(_item->url);
+ m_Revision = _item->revision;
+ m_CopyFromRevision = _item->copyfrom_rev;
+ m_CopyFromUrl = QString::FROMUTF8(_item->copyfrom_url);
+ m_State = _item->state_flags;
+ convertprop(_item->incoming_prop_changes);
+ if (_item->outgoing_prop_changes)
+ {
+ convertprop(_item->outgoing_prop_changes);
+ }
+#endif
+ }
+}
+
+void CommitItem::convertprop(apr_array_header_t * list)
+{
+ if (!list) {
+ m_CommitProperties.clear();
+ return;
+ }
+ for (int j = 0; j < list->nelts; ++j) {
+ svn_prop_t * item = ((svn_prop_t **)list->elts)[j];
+ if (!item) continue;
+ m_CommitProperties[QString::FROMUTF8(item->name)]=QString::FROMUTF8(item->value->data,item->value->len);
+ }
+}
+
+void CommitItem::init()
+{
+ m_Path=m_Url=m_CopyFromUrl = QString::null;
+ m_Kind = svn_node_unknown;
+ m_Revision=m_CopyFromRevision = -1;
+ m_State = 0;
+ m_CommitProperties.clear();
+}
+
+CommitItem::~CommitItem()
+{
+}
+
+const QString& CommitItem::path()const
+{
+ return m_Path;
+}
+
+const QString& CommitItem::url()const
+{
+ return m_Url;
+}
+
+const QString& CommitItem::copyfromurl()const
+{
+ return m_CopyFromUrl;
+}
+
+const PropertiesMap& CommitItem::properties()const
+{
+ return m_CommitProperties;
+}
+
+svn_revnum_t CommitItem::revision()const
+{
+ return m_Revision;
+}
+
+svn_revnum_t CommitItem::copyfromrevision()const
+{
+ return m_CopyFromRevision;
+}
+
+svn_node_kind_t CommitItem::kind()const
+{
+ return m_Kind;
+}
+
+apr_byte_t CommitItem::state()const
+{
+ return m_State;
+}
+
+char CommitItem::actionType()const
+{
+ char r=0;
+ if (m_State & SVN_CLIENT_COMMIT_ITEM_IS_COPY) {
+ r = 'C';
+ } else if (m_State & SVN_CLIENT_COMMIT_ITEM_ADD){
+ r = 'A';
+ } else if (m_State & SVN_CLIENT_COMMIT_ITEM_DELETE){
+ r = 'D';
+ } else if (m_State & SVN_CLIENT_COMMIT_ITEM_PROP_MODS ||
+ m_State & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS){
+ r = 'M';
+ } else if (m_State & SVN_CLIENT_COMMIT_ITEM_LOCK_TOKEN){
+ r = 'L';
+ }
+ return r;
+}
+
+}
diff --git a/src/svnqt/commititem.hpp b/src/svnqt/commititem.hpp
new file mode 100644
index 0000000..fc12def
--- /dev/null
+++ b/src/svnqt/commititem.hpp
@@ -0,0 +1,101 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef SVNCOMMITITEM_H
+#define SVNCOMMITITEM_H
+
+#include "client.hpp"
+
+#include <svn_types.h>
+#include <apr.h>
+
+// forward declarations
+struct svn_client_commit_item_t;
+// only used if build against svn 1.3 api
+struct svn_client_commit_item2_t;
+// only used if build against svn 1.5 api
+struct svn_client_commit_item3_t;
+
+namespace svn {
+
+/**
+ @author Rajko Albrecht <ral@alwins-world.de>
+*/
+class SVNQT_EXPORT CommitItem{
+
+private:
+ void init();
+ void convertprop(apr_array_header_t *);
+
+protected:
+ PropertiesMap m_CommitProperties;
+ QString m_Path,m_Url,m_CopyFromUrl;
+ svn_node_kind_t m_Kind;
+ svn_revnum_t m_Revision,m_CopyFromRevision;
+ apr_byte_t m_State;
+
+public:
+ //! constructor
+ CommitItem(const svn_client_commit_item_t*aSource=0);
+ //! constructor
+ /*!
+ * This one will only do something if build against subversion 1.3
+ */
+ CommitItem(const svn_client_commit_item2_t*);
+ /*!
+ * This one will only do something if build against subversion 1.5
+ */
+ CommitItem(const svn_client_commit_item3_t*);
+ //! Destructor
+ /*!
+ * Not virtual 'cause no child class is needed
+ */
+ ~CommitItem();
+
+ const QString& path()const;
+ const QString& url()const;
+ const QString& copyfromurl()const;
+ const PropertiesMap& properties()const;
+ svn_revnum_t revision()const;
+ svn_revnum_t copyfromrevision()const;
+ svn_node_kind_t kind()const;
+ apr_byte_t state()const;
+ //! Kind of action
+ /*!
+ * \return Char for type of action or 0 if unknown. Currently known is
+ * <UL>
+ * <LI>A - add</LI>
+ * <LI>C - copy</LI>
+ * <LI>D - deletion</LI>
+ * <LI>M - Modify (content or property)</LI>
+ * <LI>R - replaced</LI>
+ * <LI>L - (un-)lock</LI>
+ * </UL>
+ */
+ char actionType()const;
+};
+
+#if QT_VERSION < 0x040000
+ typedef QValueList<CommitItem> CommitItemList;
+#else
+ typedef QList<CommitItem> CommitItemList;
+#endif
+}
+
+#endif
diff --git a/src/svnqt/conflictdescription.cpp b/src/svnqt/conflictdescription.cpp
new file mode 100644
index 0000000..bbf059a
--- /dev/null
+++ b/src/svnqt/conflictdescription.cpp
@@ -0,0 +1,185 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Rajko Albrecht ral@alwins-world.de *
+ * http://kdesvn.alwins-world.de/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "conflictdescription.hpp"
+#include "svnqt_defines.hpp"
+
+#include <svn_wc.h>
+
+namespace svn {
+
+ConflictDescription::ConflictDescription()
+ :m_pool()
+{
+ init();
+}
+
+
+ConflictDescription::~ConflictDescription()
+{
+}
+
+ConflictDescription::ConflictDescription(const svn_wc_conflict_description_t*conflict)
+ :m_pool()
+{
+ init();
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ if (!conflict) {
+ return;
+ }
+ m_baseFile=QString::FROMUTF8(conflict->base_file);
+ m_mergedFile=QString::FROMUTF8(conflict->merged_file);
+ m_mimeType=QString::FROMUTF8(conflict->mime_type);
+ m_myFile=QString::FROMUTF8(conflict->my_file);
+ m_Path=QString::FROMUTF8(conflict->path);
+ m_propertyName=QString::FROMUTF8(conflict->property_name);
+ m_theirFile=QString::FROMUTF8(conflict->their_file);
+ switch(conflict->action) {
+ case svn_wc_conflict_action_edit:
+ m_action=ConflictEdit;
+ break;
+ case svn_wc_conflict_action_add:
+ m_action=ConflictAdd;
+ break;
+ case svn_wc_conflict_action_delete:
+ m_action=ConflictDelete;
+ break;
+ }
+ switch (conflict->kind) {
+ case svn_wc_conflict_kind_text:
+ m_Type=ConflictText;
+ break;
+ case svn_wc_conflict_kind_property:
+ m_Type=ConflictProperty;
+ break;
+ }
+ m_nodeKind=conflict->node_kind;
+ m_binary=conflict->is_binary;
+ switch (conflict->reason) {
+ case svn_wc_conflict_reason_edited:
+ m_reason=ReasonEdited;
+ break;
+ case svn_wc_conflict_reason_obstructed:
+ m_reason=ReasonObstructed;
+ break;
+ case svn_wc_conflict_reason_deleted:
+ m_reason=ReasonDeleted;
+ break;
+ case svn_wc_conflict_reason_missing:
+ m_reason=ReasonMissing;
+ break;
+ case svn_wc_conflict_reason_unversioned:
+ m_reason=ReasonUnversioned;
+ break;
+ }
+#else
+ Q_UNUSED(conflict);
+#endif
+}
+
+ConflictDescription::ConflictDescription(const ConflictDescription&)
+ :m_pool()
+{
+}
+
+}
+
+svn::ConflictDescription::ConflictAction svn::ConflictDescription::action() const
+{
+ return m_action;
+}
+
+const QString&svn::ConflictDescription::baseFile() const
+{
+ return m_baseFile;
+}
+
+
+/*!
+ \fn svn::ConflictDescription::init()
+ */
+void svn::ConflictDescription::init()
+{
+ m_baseFile=m_Path=m_mergedFile=m_propertyName=m_theirFile=m_myFile=m_mimeType=QString::null;
+ m_action=ConflictEdit;
+ m_Type=ConflictText;
+ m_reason=ReasonEdited;
+ m_binary=false;
+ m_nodeKind = svn_node_unknown;
+}
+
+
+bool svn::ConflictDescription::binary() const
+{
+ return m_binary;
+}
+
+
+const QString& svn::ConflictDescription::mergedFile() const
+{
+ return m_mergedFile;
+}
+
+
+const QString& svn::ConflictDescription::mimeType() const
+{
+ return m_mimeType;
+}
+
+
+const QString& svn::ConflictDescription::myFile() const
+{
+ return m_myFile;
+}
+
+
+svn_node_kind_t svn::ConflictDescription::nodeKind() const
+{
+ return m_nodeKind;
+}
+
+
+const QString& svn::ConflictDescription::Path() const
+{
+ return m_Path;
+}
+
+
+const QString& svn::ConflictDescription::propertyName() const
+{
+ return m_propertyName;
+}
+
+
+svn::ConflictDescription::ConflictReason svn::ConflictDescription::reason() const
+{
+ return m_reason;
+}
+
+
+const QString& svn::ConflictDescription::theirFile() const
+{
+ return m_theirFile;
+}
+
+
+svn::ConflictDescription::ConflictType svn::ConflictDescription::Type() const
+{
+ return m_Type;
+}
diff --git a/src/svnqt/conflictdescription.hpp b/src/svnqt/conflictdescription.hpp
new file mode 100644
index 0000000..3f72562
--- /dev/null
+++ b/src/svnqt/conflictdescription.hpp
@@ -0,0 +1,96 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Rajko Albrecht ral@alwins-world.de *
+ * http://kdesvn.alwins-world.de/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef SVNCONFLICTDESCRIPTION_H
+#define SVNCONFLICTDESCRIPTION_H
+
+struct svn_wc_conflict_description_t;
+
+#include "svnqt/pool.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include <svn_types.h>
+
+#include <qstring.h>
+
+namespace svn {
+
+/** Wrapper for svn_wc_conflict_description_t
+ * does nothing when build against subversion prior 1.5
+ * @since subversion 1.5
+ * @author Rajko Albrecht
+*/
+class SVNQT_EXPORT ConflictDescription
+{
+public:
+ enum ConflictType {
+ ConflictText,
+ ConflictProperty
+ };
+ enum ConflictReason {
+ ReasonEdited,
+ ReasonObstructed,
+ ReasonDeleted,
+ ReasonMissing,
+ ReasonUnversioned
+ };
+ enum ConflictAction {
+ ConflictEdit,
+ ConflictAdd,
+ ConflictDelete
+ };
+ ConflictDescription();
+ ConflictDescription(const svn_wc_conflict_description_t*);
+ ~ConflictDescription();
+
+ ConflictAction action() const;
+ ConflictType Type() const;
+ ConflictReason reason() const;
+ svn_node_kind_t nodeKind() const;
+ bool binary() const;
+ const QString& baseFile() const;
+ const QString& theirFile() const;
+ const QString& propertyName() const;
+ const QString& Path() const;
+ const QString& myFile() const;
+ const QString& mimeType() const;
+ const QString& mergedFile() const;
+
+protected:
+ //! don't use it.
+ ConflictDescription(const ConflictDescription&);
+ void init();
+protected:
+ Pool m_pool;
+ bool m_binary;
+ ConflictAction m_action;
+ ConflictType m_Type;
+ ConflictReason m_reason;
+ QString m_baseFile;
+ QString m_mergedFile;
+ QString m_mimeType;
+ QString m_myFile;
+ QString m_Path;
+ QString m_propertyName;
+ QString m_theirFile;
+ svn_node_kind_t m_nodeKind;
+};
+
+}
+
+#endif
diff --git a/src/svnqt/conflictresult.cpp b/src/svnqt/conflictresult.cpp
new file mode 100644
index 0000000..0465e33
--- /dev/null
+++ b/src/svnqt/conflictresult.cpp
@@ -0,0 +1,131 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Rajko Albrecht ral@alwins-world.de *
+ * http://kdesvn.alwins-world.de/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "conflictresult.hpp"
+
+#include "svnqt_defines.hpp"
+
+#include <svn_wc.h>
+
+namespace svn
+{
+ ConflictResult::ConflictResult()
+ :m_choice(ChooseMerged),m_MergedFile(QString::null)
+ {
+ }
+
+ ConflictResult::ConflictResult(const svn_wc_conflict_result_t*aResult)
+ {
+ if (!aResult){
+ return;
+ }
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ switch (aResult->choice){
+ case svn_wc_conflict_choose_base:
+ m_choice=ChooseBase;
+ break;
+ case svn_wc_conflict_choose_theirs_full:
+ m_choice=ChooseTheirsFull;
+ break;
+ case svn_wc_conflict_choose_mine_full:
+ m_choice=ChooseMineFull;
+ break;
+ case svn_wc_conflict_choose_theirs_conflict:
+ m_choice=ChooseTheirsConflict;
+ break;
+ case svn_wc_conflict_choose_mine_conflict:
+ m_choice=ChooseMineConflict;
+ break;
+ case svn_wc_conflict_choose_merged:
+ m_choice=ChooseMerged;
+ break;
+ case svn_wc_conflict_choose_postpone:
+ default:
+ m_choice=ChoosePostpone;
+ break;
+ }
+ if (aResult->merged_file) {
+ m_MergedFile=QString::FROMUTF8(aResult->merged_file);
+ } else {
+ m_MergedFile=QString::null;
+ }
+#else
+ Q_UNUSED(aResult);
+#endif
+ }
+
+ void ConflictResult::setMergedFile(const QString&aMergedfile) {
+ m_MergedFile=aMergedfile;
+ }
+
+ void ConflictResult::setChoice(ConflictChoice aValue)
+ {
+ m_choice=aValue;
+ }
+
+ void ConflictResult::assignResult(svn_wc_conflict_result_t**aResult,const Pool&pool)const
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ svn_wc_conflict_choice_t _choice;
+ switch (choice()) {
+ case ConflictResult::ChooseBase:
+ _choice=svn_wc_conflict_choose_base;
+ break;
+ case ConflictResult::ChooseTheirsFull:
+ _choice=svn_wc_conflict_choose_theirs_full;
+ break;
+ case ConflictResult::ChooseMineFull:
+ _choice=svn_wc_conflict_choose_mine_full;
+ break;
+ case ConflictResult::ChooseTheirsConflict:
+ _choice=svn_wc_conflict_choose_theirs_conflict;
+ break;
+ case ConflictResult::ChooseMineConflict:
+ _choice=svn_wc_conflict_choose_mine_conflict;
+ break;
+ case ConflictResult::ChooseMerged:
+ _choice=svn_wc_conflict_choose_merged;
+ break;
+ case ConflictResult::ChoosePostpone:
+ default:
+ _choice=svn_wc_conflict_choose_postpone;
+ break;
+
+ }
+ const char* _merged_file = mergedFile().isNull()?0:apr_pstrdup (pool,mergedFile().TOUTF8());
+ if ((*aResult)==0) {
+ (*aResult) = svn_wc_create_conflict_result(_choice,_merged_file,pool);
+ } else {
+ (*aResult)->choice=_choice;
+ (*aResult)->merged_file=_merged_file;
+ }
+#else
+ Q_UNUSED(aResult);
+ Q_UNUSED(pool);
+#endif
+ }
+
+ const svn_wc_conflict_result_t*ConflictResult::result(const Pool&pool)const
+ {
+ svn_wc_conflict_result_t*result=0;
+ assignResult(&result,pool);
+ return result;
+ }
+}
diff --git a/src/svnqt/conflictresult.hpp b/src/svnqt/conflictresult.hpp
new file mode 100644
index 0000000..0dfb426
--- /dev/null
+++ b/src/svnqt/conflictresult.hpp
@@ -0,0 +1,78 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Rajko Albrecht ral@alwins-world.de *
+ * http://kdesvn.alwins-world.de/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef _CONFLICT_RESULT_HPP
+#define _CONFLICT_RESULT_HPP
+
+struct svn_wc_conflict_result_t;
+
+#include "svnqt/pool.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include <svn_types.h>
+
+#include <qstring.h>
+
+namespace svn {
+
+class SVNQT_EXPORT ConflictResult
+{
+ public:
+ enum ConflictChoice {
+ //! let user make a call to resolve
+ ChoosePostpone,
+ ChooseBase,
+ ChooseTheirsFull,
+ ChooseMineFull,
+ ChooseTheirsConflict,
+ ChooseMineConflict,
+ ChooseMerged
+ };
+ ConflictResult();
+ //! Copy constructor
+ /*! only usefull wenn build with subversion 1.5 or newer
+ */
+ ConflictResult(const svn_wc_conflict_result_t*);
+
+ const QString& mergedFile()const
+ {
+ return m_MergedFile;
+ }
+ void setMergedFile(const QString&aMergedfile);
+
+ ConflictChoice choice()const
+ {
+ return m_choice;
+ }
+ void setChoice(ConflictChoice aValue);
+
+ const svn_wc_conflict_result_t*result(const Pool&pool)const;
+ void assignResult(svn_wc_conflict_result_t**aResult,const Pool&pool)const;
+
+ protected:
+ ConflictChoice m_choice;
+ //! Merged file
+ /*! will only used if m_choice is ChooseMerged
+ */
+ QString m_MergedFile;
+};
+
+}
+
+#endif
diff --git a/src/svnqt/context.cpp b/src/svnqt/context.cpp
new file mode 100644
index 0000000..56f35c0
--- /dev/null
+++ b/src/svnqt/context.cpp
@@ -0,0 +1,136 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// Apache Portable Runtime
+#include "apr_xlate.h"
+
+// Subversion api
+#include "svn_auth.h"
+#include "svn_config.h"
+#include "svn_subst.h"
+//#include "svn_utf.h"
+
+// svncpp
+#include "apr.hpp"
+#include "context.hpp"
+#include "context_listener.hpp"
+#include "contextdata.hpp"
+
+namespace svn
+{
+ Context::Context (const QString &configDir)
+ : ref_count()
+ {
+ m = new ContextData (configDir);
+ }
+
+ Context::Context (const Context & src)
+ : ref_count()
+ {
+ m = new ContextData (src.m->configDir());
+ setLogin (src.getUsername (), src.getPassword ());
+ }
+
+ Context::~Context ()
+ {
+ delete m;
+ }
+
+ void
+ Context::setAuthCache (bool value)
+ {
+ m->setAuthCache (value);
+ }
+
+ void
+ Context::setLogin (const QString& username, const QString& password)
+ {
+ m->setLogin (username, password);
+ }
+
+ Context::operator svn_client_ctx_t * ()
+ {
+ return m->ctx();
+ }
+
+ svn_client_ctx_t *
+ Context::ctx ()
+ {
+ return m->ctx();
+ }
+
+ void
+ Context::setLogMessage (const QString& msg)
+ {
+ m->setLogMessage (msg);
+ }
+
+ const QString&
+ Context::getUsername () const
+ {
+ return m->getUsername ();
+ }
+
+ const QString&
+ Context::getPassword () const
+ {
+ return m->getPassword ();
+ }
+
+ const QString&
+ Context::getLogMessage () const
+ {
+ return m->getLogMessage ();
+ }
+
+ void
+ Context::setListener (ContextListener * listener)
+ {
+ m->setListener(listener);
+ }
+
+ ContextListener *
+ Context::getListener () const
+ {
+ return m->getListener();
+ }
+
+ void
+ Context::reset ()
+ {
+ m->reset();
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/context.hpp b/src/svnqt/context.hpp
new file mode 100644
index 0000000..b45cb1c
--- /dev/null
+++ b/src/svnqt/context.hpp
@@ -0,0 +1,176 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_CONTEXT_HPP_
+#define _SVNCPP_CONTEXT_HPP_
+
+#include "svnqt/svnqt_defines.hpp"
+
+// qt
+#include <qstring.h>
+
+// Subversion api
+#include "svn_client.h"
+
+// svncpp
+#include "svnqt/pool.hpp"
+#include "svnqt/smart_pointer.hpp"
+
+
+namespace svn
+{
+ // forward declarations
+ class ContextListener;
+ class ContextData;
+
+ /**
+ * This class will hold the client context
+ * and replace the old notification and baton
+ * stuff
+ */
+ class SVNQT_EXPORT Context:public ref_count
+ {
+ public:
+ /**
+ * default constructor
+ *
+ * @param configDir location where the
+ * subversion api stores its
+ * configuration
+ */
+ Context (const QString & configDir=QString::null);
+
+ /**
+ * copy constructor
+ *
+ * @param src
+ */
+ Context (const Context &src);
+
+ /**
+ * destructor
+ */
+ virtual ~Context ();
+
+ /**
+ * enable/disable authentication caching
+ *
+ * @param value true=enable/false=disable
+ */
+ void setAuthCache (bool value);
+
+ /**
+ * set username/password for authentication
+ */
+ void setLogin (const QString& username, const QString& password);
+
+ /**
+ * operator to get svn_client_ctx object
+ */
+ operator svn_client_ctx_t * ();
+
+ /**
+ * return the svn_client_ctx object
+ */
+ svn_client_ctx_t * ctx ();
+
+ /**
+ * this will be called at the beginning of an action.
+ * the log message will be reset.
+ */
+ void reset ();
+
+ /**
+ * set log message
+ *
+ * @param msg
+ */
+ void setLogMessage (const QString& msg);
+
+ /**
+ * get log message
+ *
+ * @return log message
+ */
+ const QString&
+ getLogMessage () const;
+
+ /**
+ * get username
+ *
+ * @return username
+ */
+ const QString&
+ getUsername () const;
+
+ /**
+ * get password
+ *
+ * @return password
+ */
+ const QString&
+ getPassword () const;
+
+ /**
+ * set the listener for the context. The listener will be
+ * called to poll authentication information and other
+ * information like this
+ *
+ * @param listener
+ */
+ void
+ setListener (ContextListener * listener);
+
+ /**
+ * get the listener
+ *
+ * @return the listener
+ */
+ ContextListener *
+ getListener () const;
+
+ private:
+ ContextData * m;
+
+ /**
+ * disable assignment operator
+ */
+ Context & operator = (const Context &);
+ };
+
+ typedef svn::smart_pointer<svn::Context> ContextP;
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/context_listener.hpp b/src/svnqt/context_listener.hpp
new file mode 100644
index 0000000..8383724
--- /dev/null
+++ b/src/svnqt/context_listener.hpp
@@ -0,0 +1,271 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_CONTEXT_LISTENER_HPP_
+#define _SVNCPP_CONTEXT_LISTENER_HPP_
+
+// svncpp
+#include "svnqt/pool.hpp"
+#include "svnqt/commititem.hpp"
+#include "svnqt/svnqt_defines.hpp"
+// qt
+#include <qstring.h>
+// Subversion api
+#include <svn_client.h>
+
+
+namespace svn
+{
+ class ConflictResult;
+ class ConflictDescription;
+ /**
+ * This is the interface that is used by @a Context
+ * for callbacks.
+ * To use this you will have to inherit from this
+ * interface and overwrite the virtual methods.
+ */
+ class SVNQT_EXPORT ContextListener
+ {
+ public:
+ /**
+ * empty destructor avoids a lot of compiler warnings
+ */
+ virtual ~ContextListener(){}
+ /**
+ * this method will be called to retrieve
+ * authentication information. This will called until valid information were
+ * inserted or it returns false.
+ *
+ * @param username username set as default by subversion
+ * @param realm in which username/password will be used
+ * @param password target storage for password
+ * @param maySave in/out set false to not save
+ * @return continue action?
+ * @retval true continue
+ */
+ virtual bool
+ contextGetLogin (const QString & realm,
+ QString & username,
+ QString & password,
+ bool & maySave) = 0;
+ /**
+ * this method will be called to retrieve
+ * authentication information stored not by subversion. This
+ * will only called once!
+ *
+ * @param username username set as default by subversion
+ * @param realm in which username/password will be used
+ * @param password target storage for password
+ * @return continue action? should only in case of emergency return false.
+ * @retval true continue
+ */
+ virtual bool
+ contextGetSavedLogin(const QString & realm,
+ QString & username,
+ QString & password) = 0;
+ /**
+ * this method will be called to retrieve
+ * authentication information stored not persistent. This
+ * will only called once!
+ *
+ * @param username username set as default by subversion
+ * @param realm in which username/password will be used
+ * @param password target storage for password
+ * @return continue action? should only in case of emergency return false.
+ * @retval true continue
+ */
+ virtual bool
+ contextGetCachedLogin(const QString & realm,
+ QString & username,
+ QString & password) = 0;
+
+ /**
+ * this method will be called to notify about
+ * the progress of an ongoing action
+ *
+ * @param path
+ * @param action
+ * @param kind
+ * @param mime_type
+ * @param content_state
+ * @param prop_state
+ * @param revision
+ */
+ virtual void
+ contextNotify (const char *path,
+ svn_wc_notify_action_t action,
+ svn_node_kind_t kind,
+ const char *mime_type,
+ svn_wc_notify_state_t content_state,
+ svn_wc_notify_state_t prop_state,
+ svn_revnum_t revision) = 0;
+ /**
+ * this method will be called to notify about
+ * the progress of an ongoing action
+ *
+ * @param action the action got notified about
+ * @since subversion 1.2
+ */
+ virtual void
+ contextNotify (const svn_wc_notify_t *action) = 0;
+ /**
+ * this method will be called periodically to allow
+ * the app to cancel long running operations
+ *
+ * @return cancel action?
+ * @retval true cancel
+ */
+ virtual bool
+ contextCancel() = 0;
+
+ /**
+ * this method will be called to retrieve
+ * a log message
+ *
+ * WORKAROUND FOR apr_xlate PROBLEM:
+ * STRINGS ALREADY HAVE TO BE UTF8!!!
+ *
+ * @param msg log message
+ * @return continue action?
+ * @retval true continue
+ */
+ virtual bool
+ contextGetLogMessage (QString & msg,const CommitItemList&) = 0;
+
+ typedef enum
+ {
+ DONT_ACCEPT = 0,
+ ACCEPT_TEMPORARILY,
+ ACCEPT_PERMANENTLY
+ } SslServerTrustAnswer;
+
+
+ /**
+ * @see contextSslServerTrust
+ * @see svn_auth_cred_ssl_server_trust_t
+ */
+ struct SslServerTrustData
+ {
+ public:
+ /** bit coded failures */
+ const apr_uint32_t failures;
+
+ /** certificate information */
+ QString hostname;
+ QString fingerprint;
+ QString validFrom;
+ QString validUntil;
+ QString issuerDName;
+ QString realm;
+ bool maySave;
+
+ SslServerTrustData (const apr_uint32_t failures_)
+ : failures (failures_), hostname (""), fingerprint (""),
+ validFrom (""), validUntil (""), issuerDName (""),
+ realm (""), maySave (true)
+ {
+ }
+ };
+
+
+ /**
+ * this method is called if there is ssl server
+ * information, that has to be confirmed by the user
+ *
+ * @param data
+ * @param acceptedFailures
+ * @return @a SslServerTrustAnswer
+ */
+ virtual SslServerTrustAnswer
+ contextSslServerTrustPrompt (const SslServerTrustData & data,
+ apr_uint32_t & acceptedFailures) = 0;
+
+ /**
+ * this method is called to retrieve client side
+ * information
+ */
+ virtual bool
+ contextSslClientCertPrompt (QString & certFile) = 0;
+
+ /**
+ * this method is called to retrieve the password
+ * for the client certificate
+ *
+ * @param password
+ * @param realm
+ * @param maySave
+ */
+ virtual bool
+ contextSslClientCertPwPrompt (QString & password,
+ const QString & realm,
+ bool & maySave) = 0;
+ /**
+ * this method is called to retrieve the password
+ * for the client certificate from a local storage or such. it will called only once.
+ *
+ * @param password
+ * @param realm
+ */
+ virtual bool
+ contextLoadSslClientCertPw(QString&password,const QString&realm)=0;
+
+ virtual void
+ contextProgress(long long int current, long long int max) = 0;
+
+ /**
+ * try to translate a text. In current implementation does
+ * nothing than returning the origin but may used to get an
+ * application specific translation.
+ * @param what text to translate
+ * @return translated text or origin.
+ */
+ virtual QString translate(const QString&what){return what;}
+
+ /** Callback for svn_wc_conflict_resolver_func_t in subversion 1.5
+ * This method is only useful when build with subverion 1.5 or above. The default implementation sets
+ * result to ConflictResult::ChoosePostpone. Then conflicts while merge, update and switch results in an
+ * item with "conflict" status set.
+ *
+ * @param result The result where to store
+ * @param description description of conflict.
+ * @return true if result may used and operaion should continue.
+ * @sa svn_wc_conflict_description_t, svn_wc_conflict_result_t
+ * @since subversion 1.5
+ */
+ virtual bool contextConflictResolve(ConflictResult&result,const ConflictDescription&description);
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/contextdata.cpp b/src/svnqt/contextdata.cpp
new file mode 100644
index 0000000..b4c2ea4
--- /dev/null
+++ b/src/svnqt/contextdata.cpp
@@ -0,0 +1,782 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#include "contextdata.hpp"
+#include "context_listener.hpp"
+#include "conflictresult.hpp"
+#include "conflictdescription.hpp"
+
+#include <svn_config.h>
+#include <svn_wc.h>
+
+namespace svn {
+
+ContextData::ContextData(const QString & configDir_)
+ : listener (0), logIsSet (false),
+ m_promptCounter (0), m_ConfigDir(configDir_)
+{
+ const char * c_configDir = 0;
+ if( m_ConfigDir.length () > 0 )
+ {
+ c_configDir = m_ConfigDir.TOUTF8();
+ }
+
+ // make sure the configuration directory exists
+ svn_config_ensure (c_configDir, pool);
+
+ // intialize authentication providers
+ // * simple
+ // * username
+ // * simple pw cache of frontend app
+ // * simple pw storage
+ // * simple prompt
+ // * ssl server trust file
+ // * ssl server trust prompt
+ // * ssl client cert pw file
+ // * ssl client cert pw load
+ // * ssl client cert pw prompt
+ // * ssl client cert file
+ // ===================
+ // 11 providers (+1 for windowsvariant)
+
+ apr_array_header_t *providers =
+#if defined(WIN32) && (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ apr_array_make (pool, 12, sizeof (svn_auth_provider_object_t *));
+#else
+ apr_array_make (pool, 11, sizeof (svn_auth_provider_object_t *));
+#endif
+ svn_auth_provider_object_t *provider;
+
+#if defined(WIN32) && (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_windows_simple_provider (&provider, pool);
+ APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
+#endif
+
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_simple_provider
+#else
+ svn_client_get_simple_provider
+#endif
+ (&provider, pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_username_provider
+#else
+ svn_client_get_username_provider
+#endif
+ (&provider,pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_simple_prompt_provider
+#else
+ svn_client_get_simple_prompt_provider
+#endif
+ (&provider,onCachedPrompt,this,0,pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_simple_prompt_provider
+#else
+ svn_client_get_simple_prompt_provider
+#endif
+ (&provider,onSavedPrompt,this,0,pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_simple_prompt_provider
+#else
+ svn_client_get_simple_prompt_provider
+#endif
+ /* not very nice. should be infinite... */
+ (&provider,onSimplePrompt,this,100000000,pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+ // add ssl providers
+
+ // file first then prompt providers
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_ssl_server_trust_file_provider
+#else
+ svn_client_get_ssl_server_trust_file_provider
+#endif
+ (&provider, pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_ssl_client_cert_file_provider
+#else
+ svn_client_get_ssl_client_cert_file_provider
+#endif
+ (&provider, pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_ssl_client_cert_pw_file_provider
+#else
+ svn_client_get_ssl_client_cert_pw_file_provider
+#endif
+ (&provider, pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_ssl_server_trust_prompt_provider
+#else
+ svn_client_get_ssl_server_trust_prompt_provider
+#endif
+ (&provider, onSslServerTrustPrompt, this, pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+ // first try load from extra storage
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_ssl_client_cert_pw_prompt_provider
+#else
+ svn_client_get_ssl_client_cert_pw_prompt_provider
+#endif
+ (&provider, onFirstSslClientCertPw, this, 0, pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+ // plugged in 3 as the retry limit - what is a good limit?
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ svn_auth_get_ssl_client_cert_pw_prompt_provider
+#else
+ svn_client_get_ssl_client_cert_pw_prompt_provider
+#endif
+ (&provider, onSslClientCertPwPrompt, this, 3, pool);
+ *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
+
+ svn_auth_baton_t *ab;
+ svn_auth_open (&ab, providers, pool);
+
+ // initialize ctx structure
+ svn_client_create_context(&m_ctx,pool);
+
+ // get the config based on the configDir passed in
+ svn_config_get_config ( &(m_ctx->config), c_configDir, pool);
+
+ // tell the auth functions where the config is
+ if (c_configDir) {
+ svn_auth_set_parameter(ab, SVN_AUTH_PARAM_CONFIG_DIR,
+ c_configDir);
+ }
+
+ m_ctx->auth_baton = ab;
+ m_ctx->notify_func = onNotify;
+ m_ctx->notify_baton = this;
+ m_ctx->cancel_func = onCancel;
+ m_ctx->cancel_baton = this;
+ m_ctx->notify_func2 = onNotify2;
+ m_ctx->notify_baton2 = this;
+
+ m_ctx->log_msg_func = onLogMsg;
+ m_ctx->log_msg_baton = this;
+ // subversion 1.3 functions
+ m_ctx->log_msg_func2 = onLogMsg2;
+ m_ctx->log_msg_baton2 = this;
+
+ m_ctx->progress_func = onProgress;
+ m_ctx->progress_baton = this;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5) || (SVN_VER_MAJOR > 2))
+ m_ctx->log_msg_func3 = onLogMsg3;
+ m_ctx->log_msg_baton3 = this;
+
+ m_ctx->conflict_func = onWcConflictResolver;
+ m_ctx->conflict_baton = this;
+
+ m_ctx->client_name = "SvnQt wrapper client";
+ initMimeTypes();
+#endif
+}
+
+
+ContextData::~ContextData()
+{
+}
+
+
+const QString&ContextData::getLogMessage () const
+{
+ return logMessage;
+}
+
+bool ContextData::retrieveLogMessage (QString & msg,const CommitItemList&_itemlist)
+{
+ bool ok = false;
+ if (listener) {
+ ok = listener->contextGetLogMessage (logMessage,_itemlist);
+ if (ok)
+ msg = logMessage;
+ else
+ logIsSet = false;
+ }
+ return ok;
+}
+
+void ContextData::notify(const char *path,
+ svn_wc_notify_action_t action,
+ svn_node_kind_t kind,
+ const char *mime_type,
+ svn_wc_notify_state_t content_state,
+ svn_wc_notify_state_t prop_state,
+ svn_revnum_t revision)
+{
+ if (listener != 0) {
+ listener->contextNotify (path, action, kind, mime_type,
+ content_state, prop_state, revision);
+ }
+}
+
+void ContextData::notify (const svn_wc_notify_t *action)
+{
+ if (listener != 0) {
+ listener->contextNotify(action);
+ }
+}
+
+bool ContextData::cancel()
+{
+ if (listener != 0) {
+ return listener->contextCancel ();
+ } else {
+ // don't cancel if no listener
+ return false;
+ }
+}
+const QString& ContextData::getUsername () const
+{
+ return username;
+}
+
+const QString& ContextData::getPassword() const
+{
+ return password;
+}
+
+bool ContextData::retrieveLogin (const char * username_,
+ const char * realm,
+ bool &may_save)
+{
+ bool ok;
+
+ if (listener == 0)
+ return false;
+
+ username = QString::FROMUTF8(username_);
+ ok = listener->contextGetLogin(QString::FROMUTF8(realm),username, password, may_save);
+
+ return ok;
+}
+
+bool ContextData::retrieveSavedLogin (const char * username_,
+ const char * realm,
+ bool & may_save)
+{
+ bool ok;
+ may_save = false;
+
+ if (listener == 0)
+ return false;
+
+ username = QString::FROMUTF8(username_);
+ ok = listener->contextGetSavedLogin(QString::FROMUTF8(realm),username, password);
+ return ok;
+}
+
+bool ContextData::retrieveCachedLogin (const char * username_,
+ const char * realm,
+ bool & may_save)
+{
+ bool ok;
+ may_save = false;
+
+ if (listener == 0)
+ return false;
+
+ username = QString::FROMUTF8(username_);
+ ok = listener->contextGetCachedLogin(QString::FROMUTF8(realm),username, password);
+ return ok;
+}
+
+svn_client_ctx_t *ContextData::ctx()
+{
+ return m_ctx;
+}
+
+const QString&ContextData::configDir()const
+{
+ return m_ConfigDir;
+}
+
+svn_error_t *
+ContextData::getContextData (void * baton, ContextData ** data)
+{
+ if (baton == NULL)
+ return svn_error_create (SVN_ERR_CANCELLED, NULL,
+ "invalid baton");
+
+ ContextData * data_ = static_cast <ContextData*>(baton);
+
+ if (data_->listener == 0)
+ return svn_error_create (SVN_ERR_CANCELLED, NULL,
+ "invalid listener");
+
+ *data = data_;
+ return SVN_NO_ERROR;
+}
+
+void ContextData::setAuthCache(bool value)
+{
+ void *param = 0;
+ if (!value) {
+ param = (void *)"1";
+ }
+ svn_auth_set_parameter (m_ctx->auth_baton,
+ SVN_AUTH_PARAM_NO_AUTH_CACHE,param);
+}
+
+void ContextData::setLogin(const QString& usr, const QString& pwd)
+{
+ username = usr;
+ password = pwd;
+ svn_auth_baton_t * ab = m_ctx->auth_baton;
+ svn_auth_set_parameter (ab, SVN_AUTH_PARAM_DEFAULT_USERNAME, username.TOUTF8());
+ svn_auth_set_parameter (ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD, password.TOUTF8());
+}
+
+void ContextData::setLogMessage (const QString& msg)
+{
+ logMessage = msg;
+ if (msg.isNull()) {
+ logIsSet = false;
+ } else {
+ logIsSet = true;
+ }
+}
+
+svn_error_t *ContextData::onLogMsg (const char **log_msg,
+ const char **tmp_file,
+ apr_array_header_t * commit_items,
+ void *baton,
+ apr_pool_t * pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+
+ QString msg;
+ if (data->logIsSet) {
+ msg = data->getLogMessage ();
+ } else {
+ CommitItemList _items;
+ for (int j = 0; j < commit_items->nelts; ++j) {
+ svn_client_commit_item_t*item = ((svn_client_commit_item_t **)commit_items->elts)[j];
+ _items.push_back(CommitItem(item));
+ }
+ if (!data->retrieveLogMessage (msg,_items)) {
+ return data->generate_cancel_error();
+ }
+ }
+
+ *log_msg = apr_pstrdup (pool,msg.TOUTF8());
+ *tmp_file = NULL;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *ContextData::onLogMsg2 (const char **log_msg,
+ const char **tmp_file,
+ const apr_array_header_t * commit_items,
+ void *baton,
+ apr_pool_t * pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+
+ QString msg;
+ if (data->logIsSet) {
+ msg = data->getLogMessage ();
+ } else {
+ CommitItemList _items;
+ for (int j = 0; j < commit_items->nelts; ++j) {
+ svn_client_commit_item2_t*item = ((svn_client_commit_item2_t **)commit_items->elts)[j];
+ _items.push_back(CommitItem(item));
+ }
+
+ if (!data->retrieveLogMessage (msg,_items)) {
+ return data->generate_cancel_error();
+ }
+ }
+
+ *log_msg = apr_pstrdup (pool,msg.TOUTF8());
+ *tmp_file = NULL;
+ return SVN_NO_ERROR;
+}
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5) || (SVN_VER_MAJOR > 2))
+svn_error_t *ContextData::onLogMsg3 (const char **log_msg,
+ const char **tmp_file,
+ const apr_array_header_t * commit_items,
+ void *baton,
+ apr_pool_t * pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+
+ QString msg;
+ if (data->logIsSet) {
+ msg = data->getLogMessage ();
+ } else {
+ CommitItemList _items;
+ for (int j = 0; j < commit_items->nelts; ++j) {
+ svn_client_commit_item3_t*item = ((svn_client_commit_item3_t **)commit_items->elts)[j];
+ _items.push_back(CommitItem(item));
+ }
+
+ if (!data->retrieveLogMessage (msg,_items)) {
+ return data->generate_cancel_error();
+ }
+ }
+
+ *log_msg = apr_pstrdup (pool,msg.TOUTF8());
+ *tmp_file = NULL;
+ return SVN_NO_ERROR;
+}
+#endif
+
+void ContextData::onNotify (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)
+{
+ if (baton == 0)
+ return;
+ ContextData * data = static_cast <ContextData *> (baton);
+ data->notify (path, action, kind, mime_type, content_state,
+ prop_state, revision);
+}
+
+void ContextData::onNotify2(void*baton,const svn_wc_notify_t *action,apr_pool_t */*tpool*/)
+{
+ if (!baton) return;
+ ContextData * data = static_cast <ContextData *> (baton);
+ data->notify (action);
+}
+
+svn_error_t * ContextData::onCancel (void * baton)
+{
+ if (baton == 0) return SVN_NO_ERROR;
+ ContextData * data = static_cast <ContextData *> (baton);
+ if( data->cancel () )
+ return data->generate_cancel_error();
+ else
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *ContextData::onCachedPrompt(svn_auth_cred_simple_t **cred,
+ void *baton,
+ const char *realm,
+ const char *username,
+ svn_boolean_t _may_save,
+ apr_pool_t *pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+ bool may_save = _may_save != 0;
+ if (!data->retrieveCachedLogin (username, realm, may_save ))
+ return SVN_NO_ERROR;
+ svn_auth_cred_simple_t* lcred = (svn_auth_cred_simple_t*)
+ apr_palloc (pool, sizeof (svn_auth_cred_simple_t));
+ QByteArray l;
+ l = data->getPassword().TOUTF8();
+ lcred->password = apr_pstrndup (pool,l,l.size());
+ l = data->getUsername().TOUTF8();
+ lcred->username = apr_pstrndup (pool,l,l.size());
+
+ // tell svn if the credentials need to be saved
+ lcred->may_save = may_save;
+ *cred = lcred;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *ContextData::onSavedPrompt(svn_auth_cred_simple_t **cred,
+ void *baton,
+ const char *realm,
+ const char *username,
+ svn_boolean_t _may_save,
+ apr_pool_t *pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+ bool may_save = _may_save != 0;
+ if (!data->retrieveSavedLogin (username, realm, may_save ))
+ return SVN_NO_ERROR;
+ svn_auth_cred_simple_t* lcred = (svn_auth_cred_simple_t*)
+ apr_palloc (pool, sizeof (svn_auth_cred_simple_t));
+ QByteArray l;
+ l = data->getPassword().TOUTF8();
+ lcred->password = apr_pstrndup (pool,l,l.size());
+ l = data->getUsername().TOUTF8();
+ lcred->username = apr_pstrndup (pool,l,l.size());
+
+ // tell svn if the credentials need to be saved
+ lcred->may_save = may_save;
+ *cred = lcred;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *ContextData::onSimplePrompt (svn_auth_cred_simple_t **cred,
+ void *baton,
+ const char *realm,
+ const char *username,
+ svn_boolean_t _may_save,
+ apr_pool_t *pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+ bool may_save = _may_save != 0;
+ if (!data->retrieveLogin (username, realm, may_save ))
+ return data->generate_cancel_error();
+
+ svn_auth_cred_simple_t* lcred = (svn_auth_cred_simple_t*)
+ apr_palloc (pool, sizeof (svn_auth_cred_simple_t));
+ QByteArray l;
+ l = data->getPassword().TOUTF8();
+ lcred->password = apr_pstrndup (pool,l,l.size());
+ l = data->getUsername().TOUTF8();
+ lcred->username = apr_pstrndup (pool,l,l.size());
+
+ // tell svn if the credentials need to be saved
+ lcred->may_save = may_save;
+ *cred = lcred;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t * ContextData::onSslServerTrustPrompt (svn_auth_cred_ssl_server_trust_t **cred,
+ void *baton,
+ const char *realm,
+ apr_uint32_t failures,
+ const svn_auth_ssl_server_cert_info_t *info,
+ svn_boolean_t may_save,
+ apr_pool_t *pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+
+ ContextListener::SslServerTrustData trustData (failures);
+ if (realm != NULL)
+ trustData.realm = realm;
+ trustData.hostname = info->hostname;
+ trustData.fingerprint = info->fingerprint;
+ trustData.validFrom = info->valid_from;
+ trustData.validUntil = info->valid_until;
+ trustData.issuerDName = info->issuer_dname;
+ trustData.maySave = may_save != 0;
+
+ apr_uint32_t acceptedFailures = failures;
+ ContextListener::SslServerTrustAnswer answer =
+ data->listener->contextSslServerTrustPrompt (
+ trustData, acceptedFailures );
+
+ if(answer == ContextListener::DONT_ACCEPT) {
+ *cred = 0L;
+ } else
+ {
+ svn_auth_cred_ssl_server_trust_t *cred_ =
+ (svn_auth_cred_ssl_server_trust_t*)
+ apr_palloc (pool, sizeof (svn_auth_cred_ssl_server_trust_t));
+
+ cred_->accepted_failures = failures;
+ if (answer == ContextListener::ACCEPT_PERMANENTLY)
+ {
+ cred_->may_save = true;
+ } else {
+ cred_->may_save = false;
+ }
+ *cred = cred_;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t * ContextData::onSslClientCertPrompt (svn_auth_cred_ssl_client_cert_t **cred,
+ void *baton,
+ apr_pool_t *pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+
+ QString certFile;
+ if (!data->listener->contextSslClientCertPrompt (certFile))
+ return data->generate_cancel_error();
+
+ svn_auth_cred_ssl_client_cert_t *cred_ =
+ (svn_auth_cred_ssl_client_cert_t*)
+ apr_palloc (pool, sizeof (svn_auth_cred_ssl_client_cert_t));
+
+ cred_->cert_file = certFile.TOUTF8();
+
+ *cred = cred_;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *ContextData::onFirstSslClientCertPw (
+ svn_auth_cred_ssl_client_cert_pw_t **cred,
+ void *baton,
+ const char *realm,
+ svn_boolean_t maySave,
+ apr_pool_t *pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+
+ QString password;
+ bool may_save = maySave != 0;
+ if (!data->listener->contextLoadSslClientCertPw(password, QString::FROMUTF8(realm)))
+ return SVN_NO_ERROR;
+
+ svn_auth_cred_ssl_client_cert_pw_t *cred_ =
+ (svn_auth_cred_ssl_client_cert_pw_t *)
+ apr_palloc (pool, sizeof (svn_auth_cred_ssl_client_cert_pw_t));
+
+ cred_->password = password.TOUTF8();
+ cred_->may_save = may_save;
+ *cred = cred_;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t * ContextData::onSslClientCertPwPrompt(
+ svn_auth_cred_ssl_client_cert_pw_t **cred,
+ void *baton,
+ const char *realm,
+ svn_boolean_t maySave,
+ apr_pool_t *pool)
+{
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+
+ QString password;
+ bool may_save = maySave != 0;
+ if (!data->listener->contextSslClientCertPwPrompt (password, QString::FROMUTF8(realm), may_save))
+ return data->generate_cancel_error();
+
+ svn_auth_cred_ssl_client_cert_pw_t *cred_ =
+ (svn_auth_cred_ssl_client_cert_pw_t *)
+ apr_palloc (pool, sizeof (svn_auth_cred_ssl_client_cert_pw_t));
+
+ cred_->password = password.TOUTF8();
+ cred_->may_save = may_save;
+ *cred = cred_;
+
+ return SVN_NO_ERROR;
+}
+
+void ContextData::setListener(ContextListener * _listener)
+{
+ listener = _listener;
+}
+
+ContextListener * ContextData::getListener() const
+{
+ return listener;
+}
+
+void ContextData::reset()
+{
+ m_promptCounter = 0;
+ logIsSet = false;
+}
+
+svn_error_t * ContextData::generate_cancel_error()
+{
+ return svn_error_create (SVN_ERR_CANCELLED, 0, listener->translate(QString::FROMUTF8("Cancelled by user.")).TOUTF8());
+}
+
+void ContextData::onProgress(apr_off_t progress, apr_off_t total, void*baton, apr_pool_t*)
+{
+ ContextData * data = 0;
+ if (getContextData (baton, &data)!=SVN_NO_ERROR)
+ {
+ return;
+ }
+ data->getListener()->contextProgress(progress,total);
+}
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5) || (SVN_VER_MAJOR > 2))
+void ContextData::initMimeTypes()
+{
+ // code take from subversion 1.5 commandline client
+ const char *mimetypes_file;
+ svn_error_t * err = 0L;
+ svn_config_t * cfg = (svn_config_t *)apr_hash_get(m_ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
+ APR_HASH_KEY_STRING);
+
+ svn_config_get(cfg, &mimetypes_file,
+ SVN_CONFIG_SECTION_MISCELLANY,
+ SVN_CONFIG_OPTION_MIMETYPES_FILE, false);
+ if (mimetypes_file && *mimetypes_file) {
+ if ((err = svn_io_parse_mimetypes_file(&(m_ctx->mimetypes_map),
+ mimetypes_file, pool))) {
+ svn_handle_error2(err, stderr, false, "svn: ");
+ }
+ }
+}
+#endif
+
+svn_error_t* ContextData::onWcConflictResolver(svn_wc_conflict_result_t**result,const svn_wc_conflict_description_t *description, void *baton, apr_pool_t *pool)
+{
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5) || (SVN_VER_MAJOR > 2))
+ ContextData * data = 0;
+ SVN_ERR (getContextData (baton, &data));
+ ConflictResult cresult;
+ if (!data->getListener()->contextConflictResolve(cresult,description)) {
+ return data->generate_cancel_error();
+ }
+ cresult.assignResult(result,pool);
+ return SVN_NO_ERROR;
+#else
+ Q_UNUSED(result);
+ Q_UNUSED(description);
+ Q_UNUSED(baton);
+ Q_UNUSED(pool);
+ return svn_error_create (SVN_ERR_CANCELLED, NULL,"invalid subversion version.");
+#endif
+}
+
+bool ContextListener::contextConflictResolve(ConflictResult&result,const ConflictDescription&description)
+{
+ Q_UNUSED(description);
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5) || (SVN_VER_MAJOR > 2))
+ result.setChoice(ConflictResult::ChoosePostpone);
+#else
+ Q_UNUSED(result);
+#endif
+ return true;
+}
+
+}
diff --git a/src/svnqt/contextdata.hpp b/src/svnqt/contextdata.hpp
new file mode 100644
index 0000000..7c03f0a
--- /dev/null
+++ b/src/svnqt/contextdata.hpp
@@ -0,0 +1,338 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef SVNCONTEXTDATA_HPP
+#define SVNCONTEXTDATA_HPP
+
+#include "svnqt/pool.hpp"
+#include "svnqt/apr.hpp"
+#include "svnqt/commititem.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include <svn_client.h>
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+#include <svn_auth.h>
+#endif
+#include <qstring.h>
+
+struct svn_wc_conflict_result_t;
+struct svn_wc_conflict_description_t;
+
+namespace svn {
+
+ class ContextListener;
+/**
+ @author Rajko Albrecht <ral@alwins-world.de>
+*/
+
+class SVNQT_NOEXPORT ContextData{
+public:
+ ContextData(const QString & configDir_);
+ ~ContextData();
+
+ // data methods
+ svn_client_ctx_t*ctx();
+ const QString&configDir()const;
+ void setListener (ContextListener * listener);
+ ContextListener * getListener () const;
+ void reset();
+
+ // svn methods
+ void setAuthCache(bool value);
+ /** @see Context::setLogin */
+ void setLogin (const QString& usr, const QString& pwd);
+ /** @see Context::setLogMessage */
+ void setLogMessage (const QString& msg);
+ const QString&getLogMessage ()const;
+ /**
+ * if the @a listener is set, use it to retrieve the log
+ * message using ContextListener::contextGetLogMessage.
+ * This return values is given back, then.
+ *
+ * if the @a listener is not set the its checked whether
+ * the log message has been set using @a setLogMessage
+ * yet. If not, return false otherwise true
+ *
+ * @param msg log message
+ * @retval false cancel
+ */
+ bool retrieveLogMessage (QString & msg,const CommitItemList&);
+
+ /**
+ * if the @a listener is set call the method
+ * @a contextNotify
+ */
+ void notify (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);
+ void notify (const svn_wc_notify_t *action);
+ /**
+ * if the @a listener is set call the method
+ * @a contextCancel
+ */
+ bool cancel();
+ const QString& getUsername () const;
+ const QString& getPassword () const;
+
+ /**
+ * if the @a listener is set and no password has been
+ * set yet, use it to retrieve login and password using
+ * ContextListener::contextGetLogin.
+ *
+ * if the @a listener is not set, check if setLogin
+ * has been called yet.
+ *
+ * @return continue?
+ * @retval false cancel
+ */
+ bool
+ retrieveLogin (const char * username_,
+ const char * realm,
+ bool &may_save);
+ /**
+ * if the @a listener is set and no password has been
+ * set yet, use it to retrieve login and password using
+ * ContextListener::contextGetSavedLogin.
+ *
+ * if the @a listener is not set, check if setLogin
+ * has been called yet.
+ *
+ * @return continue?
+ * @retval false cancel
+ */
+ bool
+ retrieveSavedLogin(const char * username_,
+ const char * realm,
+ bool &may_save);
+ /**
+ * if the @a listener is set and no password has been
+ * set yet, use it to retrieve login and password using
+ * ContextListener::contextGetCachedLogin.
+ *
+ * if the @a listener is not set, check if setLogin
+ * has been called yet.
+ *
+ * @return continue?
+ * @retval false cancel
+ */
+ bool
+ retrieveCachedLogin(const char * username_,
+ const char * realm,
+ bool &may_save);
+
+protected:
+ // static methods
+ /**
+ * the @a baton is interpreted as ContextData *
+ * Several checks are performed on the baton:
+ * - baton == 0?
+ * - baton->Data
+ * - listener set?
+ *
+ * @param baton
+ * @param data returned data if everything is OK
+ * @retval SVN_NO_ERROR if everything is fine
+ * @retval SVN_ERR_CANCELLED on invalid values
+ */
+ static svn_error_t *
+ getContextData (void * baton, ContextData ** data);
+
+ /**
+ * this function gets called by the subversion api function
+ * when a log message is needed. This is the case on a commit
+ * for example
+ */
+ static svn_error_t *
+ onLogMsg (const char **log_msg,
+ const char **tmp_file,
+ apr_array_header_t * commit_items,
+ void *baton,
+ apr_pool_t * pool);
+
+ /**
+ * this function gets called by the subversion api function
+ * when a log message is needed. This is the case on a commit
+ * for example
+ */
+ static svn_error_t *
+ onLogMsg2 (const char **log_msg,
+ const char **tmp_file,
+ const apr_array_header_t * commit_items,
+ void *baton,
+ apr_pool_t * pool);
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5) || (SVN_VER_MAJOR > 2))
+ /**
+ * this function gets called by the subversion api function
+ * when a log message is needed. This is the case on a commit
+ * for example
+ */
+ static svn_error_t *
+ onLogMsg3 (const char **log_msg,
+ const char **tmp_file,
+ const apr_array_header_t * commit_items,
+ void *baton,
+ apr_pool_t * pool);
+#endif
+
+ /**
+ * this is the callback function for the subversion
+ * api functions to signal the progress of an action
+ */
+ static void
+ onNotify (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);
+ /**
+ * this is the callback function for the subversion 1.2
+ * api functions to signal the progress of an action
+ *
+ * @todo right now we forward only to @a onNotify,
+ * but maybe we should a notify2 to the listener
+ * @since subversion 1.2
+ */
+ static void
+ onNotify2(void*baton,const svn_wc_notify_t *action,apr_pool_t */*tpool*/);
+ /**
+ * this is the callback function for the subversion
+ * api functions to signal the progress of an action
+ * @param baton pointer to a ContextData instance
+ */
+ static svn_error_t * onCancel (void * baton);
+
+ /**
+ * @see svn_auth_simple_prompt_func_t
+ * this method is an alternate and called ONEs before onSimplePrompt.
+ * So we can try load password from other source.
+ */
+ static svn_error_t *
+ onCachedPrompt(svn_auth_cred_simple_t **cred,
+ void *baton,
+ const char *realm,
+ const char *username,
+ svn_boolean_t _may_save,
+ apr_pool_t *pool);
+
+ /**
+ * @see svn_auth_simple_prompt_func_t
+ * this method is an alternate and called ONEs before onSimplePrompt.
+ * So we can try load password from other source.
+ */
+ static svn_error_t *
+ onSavedPrompt(svn_auth_cred_simple_t **cred,
+ void *baton,
+ const char *realm,
+ const char *username,
+ svn_boolean_t _may_save,
+ apr_pool_t *pool);
+ /**
+ * @see svn_auth_simple_prompt_func_t
+ */
+ static svn_error_t *
+ onSimplePrompt (svn_auth_cred_simple_t **cred,
+ void *baton,
+ const char *realm,
+ const char *username,
+ svn_boolean_t _may_save,
+ apr_pool_t *pool);
+ /**
+ * @see svn_auth_ssl_server_trust_prompt_func_t
+ */
+ static svn_error_t *
+ onSslServerTrustPrompt (svn_auth_cred_ssl_server_trust_t **cred,
+ void *baton,
+ const char *realm,
+ apr_uint32_t failures,
+ const svn_auth_ssl_server_cert_info_t *info,
+ svn_boolean_t may_save,
+ apr_pool_t *pool);
+ static svn_error_t *
+ onSslClientCertPrompt (svn_auth_cred_ssl_client_cert_t **cred,
+ void *baton,
+ apr_pool_t *pool);
+ /**
+ * @see svn_auth_ssl_client_cert_pw_prompt_func_t
+ */
+ static svn_error_t *
+ onFirstSslClientCertPw (
+ svn_auth_cred_ssl_client_cert_pw_t **cred,
+ void *baton,
+ const char *realm,
+ svn_boolean_t maySave,
+ apr_pool_t *pool);
+
+ /**
+ * @see svn_auth_ssl_client_cert_pw_prompt_func_t
+ */
+ static svn_error_t *
+ onSslClientCertPwPrompt (
+ svn_auth_cred_ssl_client_cert_pw_t **cred,
+ void *baton,
+ const char *realm,
+ svn_boolean_t maySave,
+ apr_pool_t *pool);
+
+ /**
+ * @see svn_client_ctx_t::progress_func
+ */
+ static void onProgress(apr_off_t progress, apr_off_t total, void *baton, apr_pool_t *pool);
+
+ /**
+ * @see svn_wc_conflict_resolver_func_t
+ * @since subversion 1.5
+ */
+ static svn_error_t* onWcConflictResolver(svn_wc_conflict_result_t**result,const svn_wc_conflict_description_t *description, void *baton, apr_pool_t *pool);
+
+ // extra methods
+ svn_error_t *
+ generate_cancel_error();
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5) || (SVN_VER_MAJOR > 2))
+ /** read in mimetypes map
+ * @since subversion 1.5
+ */
+ void initMimeTypes();
+#endif
+protected:
+ Apr apr;
+
+ ContextListener * listener;
+ bool logIsSet;
+ int m_promptCounter;
+ Pool pool;
+ svn_client_ctx_t*m_ctx;
+ QString username;
+ QString password;
+ QString logMessage;
+ QString m_ConfigDir;
+
+};
+
+}
+
+#endif
diff --git a/src/svnqt/datetime.cpp b/src/svnqt/datetime.cpp
new file mode 100644
index 0000000..496a04b
--- /dev/null
+++ b/src/svnqt/datetime.cpp
@@ -0,0 +1,170 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// apr
+#include "apr_date.h"
+
+// svncpp
+#include "datetime.hpp"
+
+
+namespace svn
+{
+ DateTime::DateTime ()
+ : m_time()
+ {
+ }
+
+ DateTime::DateTime (const apr_time_t time)
+ : m_time()
+ {
+ setAprTime(time);
+ }
+
+ DateTime::DateTime(const QDateTime&dt)
+ : m_time(dt)
+ {
+ }
+
+ DateTime::DateTime (const DateTime & dateTime)
+ : m_time(dateTime.m_time)
+ {
+ }
+
+ const DateTime &
+ DateTime::operator =(const DateTime & dateTime)
+ {
+ m_time = dateTime.m_time;
+ return *this;
+ }
+
+ bool DateTime::operator<(const DateTime&dateTime)const
+ {
+ return m_time<dateTime.m_time;
+ }
+
+ bool DateTime::operator>(const DateTime&dateTime)const
+ {
+ return dateTime<*this;
+ }
+
+ bool DateTime::operator!=(const DateTime&dateTime)const
+ {
+ return *this<dateTime||dateTime<*this;
+ }
+ bool DateTime::operator==(const DateTime&dateTime)const
+ {
+ return !(*this!=dateTime);
+ }
+
+ bool
+ DateTime::operator ==(const DateTime & dateTime)
+ {
+ return m_time == dateTime.m_time;
+ }
+
+ bool
+ DateTime::operator !=(const DateTime & dateTime)
+ {
+ return m_time != dateTime.m_time;
+ }
+ bool
+ DateTime::operator<=(const DateTime&dateTime)const
+ {
+ return *this==dateTime||*this<dateTime;
+ }
+ bool
+ DateTime::operator>=(const DateTime&dateTime)const
+ {
+ return *this==dateTime||*this>dateTime;
+ }
+
+ bool
+ DateTime::IsValid () const
+ {
+ return m_time.isValid();
+ }
+
+ apr_time_t
+ DateTime::GetAPRTimeT () const
+ {
+ apr_time_t aTime;
+ apr_time_ansi_put(&aTime,m_time.toTime_t());
+ return aTime;
+ }
+
+ bool
+ DateTime::SetRFC822Date (const char* date)
+ {
+ apr_time_t aTime = apr_date_parse_rfc(date);
+ setAprTime(aTime);
+ return IsValid();
+ }
+
+ DateTime::operator const QDateTime&()const
+ {
+ return m_time;
+ }
+
+ const QDateTime&DateTime::toQDateTime()const
+ {
+ return *this;
+ }
+
+ void DateTime::setAprTime(apr_time_t aTime)
+ {
+#if QT_VERSION < 0x040000
+ if (aTime<0)m_time.setTime_t(0,Qt::LocalTime);
+ else m_time.setTime_t(aTime/(1000*1000),Qt::LocalTime);
+#else
+ m_time.setTimeSpec(Qt::LocalTime);
+ if (aTime<0)m_time.setTime_t(0);
+ else m_time.setTime_t(aTime/(1000*1000));
+#endif
+ }
+
+ QString DateTime::toString(const QString&format)const
+ {
+ return m_time.toString(format);
+ }
+}
+
+/*!
+ \fn svn::DateTime::toTime_t()
+ */
+unsigned int svn::DateTime::toTime_t()const
+{
+ return m_time.toTime_t();
+}
+
+void svn::DateTime::setTime_t(unsigned int sec)
+{
+ m_time.setTime_t(sec);
+}
diff --git a/src/svnqt/datetime.hpp b/src/svnqt/datetime.hpp
new file mode 100644
index 0000000..06fedb4
--- /dev/null
+++ b/src/svnqt/datetime.hpp
@@ -0,0 +1,166 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_DATETIME_HPP_
+#define _SVNCPP_DATETIME_HPP_
+
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qdatetime.h>
+
+// subversion api
+#include "svn_types.h"
+
+
+namespace svn
+{
+ /**
+ * Class that encapsulates apr_time_t.
+ *
+ * @see apr_time_t
+ */
+ class SVNQT_EXPORT DateTime
+ {
+ private:
+ QDateTime m_time;
+
+ public:
+
+ /**
+ * Default Constructor
+ */
+ DateTime ();
+
+ /**
+ * Constructor
+ *
+ * @param time number of microseconds since 00:00:00 january 1, 1970 UTC
+ */
+ DateTime (const apr_time_t time);
+
+ /**
+ * Constructor
+ *
+ * @param dt QDateTime class
+ */
+ DateTime(const QDateTime&dt);
+
+ /**
+ * Copy constructor
+ *
+ * @param dateTime Source
+ */
+ DateTime (const DateTime & dateTime);
+
+ /**
+ * @param dateTime Source
+ */
+ const DateTime &
+ operator =(const DateTime & dateTime);
+
+ /**
+ * @param dateTime Comparator
+ */
+ bool
+ operator ==(const DateTime & dateTime);
+ /**
+ * @param dateTime Comparator
+ */
+ bool
+ operator !=(const DateTime & dateTime);
+
+ bool
+ operator<(const DateTime&dateTime)const;
+ bool
+ operator>(const DateTime&dateTime)const;
+ bool
+ operator!=(const DateTime&dateTime)const;
+ bool
+ operator==(const DateTime&dateTime)const;
+ bool
+ operator<=(const DateTime&dateTime)const;
+ bool
+ operator>=(const DateTime&dateTime)const;
+
+
+ /**
+ * @return Is a valid (non-zero) date
+ */
+ bool
+ IsValid () const;
+
+ /**
+ * @return APR apr_time_t
+ */
+ apr_time_t
+ GetAPRTimeT () const;
+
+ /**
+ * @return QDateTime object
+ */
+ operator const QDateTime&()const;
+
+ /**
+ * @return QDateTime object
+ */
+ const QDateTime&toQDateTime()const;
+
+ /**
+ * @param format format string
+ * @return formatted string
+ * @see QDateTime::toString
+ */
+ QString toString(const QString&format)const;
+
+ /**
+ * Set from date string of the form below, using apr_date_parse_rfc
+ *
+ * <PRE>
+ * Sun, 06 Nov 1994 08:49:37 GMT
+ * </PRE>
+ *
+ * @see apr_date_parse_rfc
+ * @return Successfully parsed
+ */
+ bool
+ SetRFC822Date (const char* date);
+
+ void setAprTime(apr_time_t aTime);
+ unsigned int toTime_t()const;
+ void setTime_t(unsigned int sec);
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/diff_data.cpp b/src/svnqt/diff_data.cpp
new file mode 100644
index 0000000..a5f66f9
--- /dev/null
+++ b/src/svnqt/diff_data.cpp
@@ -0,0 +1,145 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Rajko Albrecht ral@alwins-world.de *
+ * http://kdesvn.alwins-world.de/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "diff_data.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/exception.hpp"
+
+#include <qfile.h>
+
+#include <svn_version.h>
+#include <svn_io.h>
+#include <svn_path.h>
+
+namespace svn
+{
+ DiffData::DiffData(const Path&aTmpPath,const Path&_p1,const Revision&_r1,const Path&_p2,const Revision&_r2)
+ :m_Pool(),m_tmpPath(aTmpPath),
+ m_outFile(0),m_errFile(0),m_outFileName(0),m_errFileName(0),
+ m_p1(_p1),m_p2(_p2),m_r1(_r1),m_r2(_r2),
+ m_working_copy_present(false),m_url_is_present(false)
+ {
+ init();
+ }
+
+ void DiffData::init()
+ {
+ svn_error_t * error;
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ error = svn_io_open_unique_file2(&m_outFile, &m_outFileName,
+ m_tmpPath.path().TOUTF8(),
+ ".tmp",
+ svn_io_file_del_on_pool_cleanup, m_Pool);
+#else
+ error = svn_io_open_unique_file (&m_outFile, &m_outFileName,
+ m_tmpPath.path().TOUTF8(),
+ ".tmp",
+ FALSE, m_Pool);
+#endif
+ if (error!=0) {
+ clean();
+ throw ClientException (error);
+ }
+#if (SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4)
+ error = svn_io_open_unique_file2(&m_errFile, &m_errFileName,
+ m_tmpPath.path().TOUTF8(),
+ ".tmp",
+ svn_io_file_del_on_pool_cleanup, m_Pool);
+#else
+ error = svn_io_open_unique_file (&m_errFile, &m_errFileName,
+ m_tmpPath.path().TOUTF8(),
+ ".tmp",
+ FALSE, m_Pool);
+#endif
+ if (error!=0) {
+ clean();
+ throw ClientException (error);
+ }
+ if (svn_path_is_url(m_p1.cstr())) {
+ m_url_is_present = true;
+ } else {
+ m_working_copy_present = true;
+ }
+ if (svn_path_is_url(m_p2.cstr())) {
+ m_url_is_present = true;
+ } else {
+ m_working_copy_present = true;
+ }
+
+ if (m_r1.revision()->kind==svn_opt_revision_unspecified && m_working_copy_present) {
+ m_r1 = svn_opt_revision_base;
+ }
+ if (m_r2.revision()->kind==svn_opt_revision_unspecified) {
+ m_r2 = m_working_copy_present?svn_opt_revision_working : svn_opt_revision_head;
+ }
+ }
+
+ DiffData::~DiffData()
+ {
+ clean();
+ }
+
+ void DiffData::clean()
+ {
+ close();
+#if !((SVN_VER_MAJOR >= 1) && (SVN_VER_MINOR >= 4))
+ if (m_outFileName != 0) {
+ svn_error_clear (svn_io_remove_file (m_outFileName, m_Pool));
+ m_outFileName=0;
+ }
+ if (m_errFileName != 0) {
+ svn_error_clear (svn_io_remove_file (m_errFileName, m_Pool));
+ m_errFileName=0;
+ }
+#endif
+ }
+
+ void DiffData::close()
+ {
+ if (m_outFile != 0) {
+ svn_io_file_close(m_outFile,m_Pool);
+ m_outFile=0;
+ }
+ if (m_errFile != 0) {
+ svn_io_file_close(m_errFile,m_Pool);
+ m_errFile=0;
+ }
+ }
+
+ QByteArray DiffData::content()
+ {
+ if (!m_outFileName) {
+ return QByteArray();
+ }
+ close();
+ QFile fi(m_outFileName);
+#if QT_VERSION < 0x040000
+ if (!fi.open(IO_ReadOnly|IO_Raw)) {
+ throw ClientException(QString("%1 '%2'").arg(fi.errorString()).arg(m_outFileName));
+#else
+ if (!fi.open(QIODevice::ReadOnly)) {
+ throw ClientException(QString("%1 '%2'").arg(fi.errorString()).arg(m_outFileName).toLatin1().constData());
+#endif
+ }
+
+ QByteArray res = fi.readAll();
+ fi.close();
+ return res;
+ }
+}
diff --git a/src/svnqt/diff_data.hpp b/src/svnqt/diff_data.hpp
new file mode 100644
index 0000000..c92c8ac
--- /dev/null
+++ b/src/svnqt/diff_data.hpp
@@ -0,0 +1,75 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Rajko Albrecht ral@alwins-world.de *
+ * http://kdesvn.alwins-world.de/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef __DIFF_DATA
+#define __DIFF_DATA
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/pool.hpp"
+#include "path.hpp"
+#include "revision.hpp"
+
+#include <qglobal.h>
+
+#if QT_VERSION < 0x040000
+ #include <qstring.h>
+#else
+ #include <QtCore>
+#endif
+
+struct apr_file_t;
+
+namespace svn
+{
+ class Path;
+
+ class SVNQT_NOEXPORT DiffData
+ {
+ protected:
+ Pool m_Pool;
+ Path m_tmpPath;
+ apr_file_t*m_outFile;
+ apr_file_t*m_errFile;
+ const char*m_outFileName;
+ const char*m_errFileName;
+
+ Path m_p1,m_p2;
+ Revision m_r1,m_r2;
+
+ bool m_working_copy_present,m_url_is_present;
+
+ void init();
+ void clean();
+ void close();
+
+ public:
+ DiffData(const Path&aTmpPath,const Path&,const Revision&,const Path&,const Revision&);
+ virtual ~DiffData();
+
+ apr_file_t*outFile(){return m_outFile;}
+ apr_file_t*errFile(){return m_errFile;}
+ const Revision& r1()const{return m_r1;}
+ const Revision& r2()const{return m_r2;}
+
+ QByteArray content();
+ };
+}
+
+#endif
diff --git a/src/svnqt/diffoptions.cpp b/src/svnqt/diffoptions.cpp
new file mode 100644
index 0000000..7ada9c8
--- /dev/null
+++ b/src/svnqt/diffoptions.cpp
@@ -0,0 +1,144 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Rajko Albrecht ral@alwins-world.de *
+ * http://kdesvn.alwins-world.de/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "diffoptions.hpp"
+#include "stringarray.hpp"
+#include "pool.hpp"
+
+#include <svn_diff.h>
+
+namespace svn
+{
+ struct DiffOptionsData
+ {
+ DiffOptions::IgnoreSpace _ignorespace;
+ bool _ignoreeol;
+ bool _showc;
+
+ DiffOptionsData()
+ {
+ _ignorespace=DiffOptions::IgnoreSpaceNone;
+ _ignoreeol = _showc = false;
+ }
+ };
+
+ DiffOptions::DiffOptions()
+ :m_data(new DiffOptionsData())
+ {
+ }
+
+ void DiffOptions::init(const svn_diff_file_options_t*_diffopts)
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ m_data->_ignoreeol = _diffopts->ignore_eol_style;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ m_data->_showc = _diffopts->show_c_function;
+#else
+ m_data->_showc = false;
+#endif
+ switch (_diffopts->ignore_space) {
+ case svn_diff_file_ignore_space_change:
+ m_data->_ignorespace = IgnoreSpaceChange;
+ break;
+ case svn_diff_file_ignore_space_all:
+ m_data->_ignorespace = IgnoreSpaceAll;
+ break;
+ case svn_diff_file_ignore_space_none:
+ default:
+ m_data->_ignorespace = IgnoreSpaceNone;
+ break;
+ }
+#else
+ Q_UNUSED(_diffopts);
+#endif
+ }
+
+ DiffOptions::DiffOptions(const QStringList&options)
+ :m_data(new DiffOptionsData())
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ Pool pool;
+ StringArray _ar(options);
+ svn_diff_file_options_t * _diffopts = svn_diff_file_options_create(pool);
+ if (_diffopts) {
+ svn_error_t*error = svn_diff_file_options_parse(_diffopts,_ar.array(pool),pool);
+ if (error==0) {
+ init(_diffopts);
+ }
+ }
+#else
+ Q_UNUSED(options)
+#endif
+ }
+
+ DiffOptions::DiffOptions(const svn_diff_file_options_t*options)
+ :m_data(new DiffOptionsData())
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ if (options) {
+ init(options);
+ }
+#else
+ Q_UNUSED(options)
+#endif
+ }
+
+ svn_diff_file_options_t*DiffOptions::options(const Pool&pool)const
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4)) || (SVN_VER_MAJOR > 1)
+ svn_diff_file_options_t * _diffopts = svn_diff_file_options_create(pool);
+ _diffopts->ignore_eol_style = m_data->_ignoreeol;
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ _diffopts->show_c_function = m_data->_showc;
+#endif
+ switch (m_data->_ignorespace) {
+ case IgnoreSpaceChange:
+ _diffopts->ignore_space=svn_diff_file_ignore_space_change;
+ break;
+ case IgnoreSpaceAll:
+ _diffopts->ignore_space=svn_diff_file_ignore_space_all;
+ break;
+ case IgnoreSpaceNone:
+ default:
+ _diffopts->ignore_space=svn_diff_file_ignore_space_none;
+ break;
+ }
+ return _diffopts;
+#else
+ Q_UNUSED(pool);
+ return 0;
+#endif
+ }
+
+ DiffOptions::DiffOptions(const DiffOptions&old)
+ :m_data(new DiffOptionsData())
+ {
+ m_data->_showc = old.m_data->_showc;
+ m_data->_ignorespace=old.m_data->_ignorespace;
+ m_data->_ignoreeol=old.m_data->_ignoreeol;
+ }
+
+ DiffOptions::~DiffOptions()
+ {
+ delete m_data;
+ m_data=0;
+ }
+}
diff --git a/src/svnqt/diffoptions.hpp b/src/svnqt/diffoptions.hpp
new file mode 100644
index 0000000..5509821
--- /dev/null
+++ b/src/svnqt/diffoptions.hpp
@@ -0,0 +1,79 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Rajko Albrecht ral@alwins-world.de *
+ * http://kdesvn.alwins-world.de/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef _DIFF_OPTIONS_HPP
+#define _DIFF_OPTIONS_HPP
+
+#include "svnqt/svnqt_defines.hpp"
+
+namespace svn {
+ class Pool;
+ struct DiffOptionsData;
+}
+
+struct svn_diff_file_options_t;
+class QStringList;
+
+namespace svn
+{
+ /** c++ wrapper for svn_diffoptions_t
+ *
+ * This is needed until svnqt stops support for subversion prior 1.4
+ */
+ class SVNQT_EXPORT DiffOptions
+ {
+ public:
+ enum IgnoreSpace {
+ IgnoreSpaceNone,
+ IgnoreSpaceChange,
+ IgnoreSpaceAll
+ };
+ protected:
+ DiffOptionsData* m_data;
+ void init(const svn_diff_file_options_t*options);
+
+ public:
+ DiffOptions();
+ /** Initialize options with values depending on options.
+ * Supported types are:
+ * - --ignore-space-change, -b
+ * - --ignore-all-space, -w
+ * - --ignore-eol-style
+ * - --unified, -u (for compatibility, does nothing).
+ * @sa svn_diff_file_options_parse
+ */
+ DiffOptions(const QStringList&options);
+
+ /** Initialize options with values depending on options.
+ * Only if build against subversion 1.4 or newer.
+ */
+ DiffOptions(const svn_diff_file_options_t*options);
+
+ /** copy operator
+ */
+ DiffOptions(const DiffOptions&old);
+
+ ~DiffOptions();
+
+ svn_diff_file_options_t*options(const Pool&pool)const;
+ };
+}
+
+#endif
diff --git a/src/svnqt/dirent.cpp b/src/svnqt/dirent.cpp
new file mode 100644
index 0000000..480546f
--- /dev/null
+++ b/src/svnqt/dirent.cpp
@@ -0,0 +1,186 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// svncpp
+#include "svnqt/dirent.hpp"
+#include "svnqt/lock_entry.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qstring.h>
+
+namespace svn
+{
+ class SVNQT_NOEXPORT DirEntry_Data
+ {
+ public:
+ QString name;
+ svn_node_kind_t kind;
+ QLONG size;
+ bool hasProps;
+ svn_revnum_t createdRev;
+ DateTime time;
+ QString lastAuthor;
+ LockEntry m_Lock;
+
+ DirEntry_Data ()
+ : kind (svn_node_unknown), size (0), hasProps(false),
+ createdRev (0), time (0), m_Lock()
+ {
+ }
+
+ DirEntry_Data (const QString& _name, const svn_dirent_t * dirEntry)
+ : name (_name), kind (dirEntry->kind), size (dirEntry->size),
+ hasProps (dirEntry->has_props != 0),
+ createdRev (dirEntry->created_rev), time (dirEntry->time), m_Lock()
+ {
+ lastAuthor = dirEntry->last_author == 0 ? QString::fromLatin1("") : QString::FROMUTF8(dirEntry->last_author);
+ }
+
+ DirEntry_Data (const DirEntry & src)
+ {
+ init (src);
+ }
+
+ void
+ init (const DirEntry & src)
+ {
+ name = src.name ();
+ kind = src.kind ();
+ size = src.size ();
+ hasProps = src.hasProps ();
+ createdRev = src.createdRev ();
+ time = src.time ();
+ lastAuthor = src.lastAuthor ();
+ m_Lock = src.lockEntry();
+ }
+ };
+
+ DirEntry::DirEntry ()
+ : m (new DirEntry_Data ())
+ {
+ }
+
+ DirEntry::DirEntry (const QString& name, const svn_dirent_t * dirEntry)
+ : m (new DirEntry_Data (name, dirEntry))
+ {
+ }
+
+ DirEntry::DirEntry (const QString& name, const svn_dirent_t * dirEntry,const svn_lock_t*lockEntry)
+ : m (new DirEntry_Data (name, dirEntry))
+ {
+ setLock(lockEntry);
+ }
+
+ DirEntry::DirEntry (const QString& name, const svn_dirent_t * dirEntry,const LockEntry&lockEntry)
+ : m (new DirEntry_Data (name, dirEntry))
+ {
+ m->m_Lock = lockEntry;
+ }
+
+ DirEntry::DirEntry (const DirEntry & src)
+ : m (new DirEntry_Data (src))
+ {
+ }
+
+ DirEntry::~DirEntry ()
+ {
+ delete m;
+ }
+
+ svn_node_kind_t
+ DirEntry::kind () const
+ {
+ return m->kind;
+ }
+
+ QLONG
+ DirEntry::size () const
+ {
+ return m->size;
+ }
+
+ bool
+ DirEntry::hasProps () const
+ {
+ return m->hasProps;
+ }
+
+ svn_revnum_t
+ DirEntry::createdRev () const
+ {
+ return m->createdRev;
+ }
+
+ const DateTime&
+ DirEntry::time () const
+ {
+ return m->time;
+ }
+
+ const QString&
+ DirEntry::lastAuthor () const
+ {
+ return m->lastAuthor;
+ }
+
+ const QString&
+ DirEntry::name () const
+ {
+ return m->name;
+ }
+
+ const LockEntry&
+ DirEntry::lockEntry() const
+ {
+ return m->m_Lock;
+ }
+
+ void
+ DirEntry::setLock(const svn_lock_t*_l)
+ {
+ m->m_Lock.init(_l);
+ }
+
+ DirEntry &
+ DirEntry::operator= (const DirEntry & dirEntry)
+ {
+ if (this == &dirEntry)
+ return *this;
+
+ m->init (dirEntry);
+ return *this;
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/dirent.hpp b/src/svnqt/dirent.hpp
new file mode 100644
index 0000000..9b7c3e2
--- /dev/null
+++ b/src/svnqt/dirent.hpp
@@ -0,0 +1,131 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_DIRENT_HPP_
+#define _SVNCPP_DIRENT_HPP_
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/lock_entry.hpp"
+#include "svnqt/datetime.hpp"
+
+// subversion api
+#include "svn_client.h"
+
+#include <qstring.h>
+
+namespace svn
+{
+ class DirEntry_Data;
+
+ class SVNQT_EXPORT DirEntry
+ {
+ public:
+ /**
+ * default constructor
+ */
+ DirEntry ();
+
+ /**
+ * constructor for existing @a svn_dirent_t entries
+ */
+ DirEntry (const QString& name, const svn_dirent_t * dirEntry);
+ /**
+ * constructor for existing @a svn_dirent_t entries
+ */
+ DirEntry (const QString& name, const svn_dirent_t * dirEntry,const svn_lock_t*lockEntry);
+
+ DirEntry (const QString& name, const svn_dirent_t * dirEntry,const LockEntry&lockEntry);
+ /**
+ * copy constructor
+ */
+ DirEntry (const DirEntry & src);
+
+ /**
+ * destructor
+ */
+ ~DirEntry ();
+
+ /**
+ * assignment operator
+ */
+ DirEntry &
+ operator = (const DirEntry &);
+
+ const QString&
+ name () const;
+
+ svn_node_kind_t
+ kind () const;
+
+ QLONG
+ size () const;
+
+ bool
+ hasProps () const;
+
+ svn_revnum_t
+ createdRev () const;
+
+ const DateTime&
+ time () const;
+
+ const QString&
+ lastAuthor () const;
+
+ //! The assigned lock entry
+ /*!
+ * returns the assigned lock entry if set
+ * \return a valid or an empty lock
+ */
+ const LockEntry&
+ lockEntry() const;
+
+ //! initialize and convert the internal lock entry
+ /*!
+ * This method should not needed to call outside the lib, it may just used
+ * inside svn::Client::ls.
+ * \param aLock the subversion lock description to convert.
+ */
+ void
+ setLock(const svn_lock_t*aLock);
+
+
+ private:
+ DirEntry_Data * m;
+
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/entry.cpp b/src/svnqt/entry.cpp
new file mode 100644
index 0000000..27c14cf
--- /dev/null
+++ b/src/svnqt/entry.cpp
@@ -0,0 +1,394 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// svncpp
+#include "entry.hpp"
+
+namespace svn
+{
+ class SVNQT_NOEXPORT Entry_private
+ {
+ protected:
+ void init_clean();
+ public:
+ Entry_private();
+ Entry_private(const Entry_private&src);
+ virtual ~Entry_private();
+
+ bool m_valid;
+ LockEntry m_Lock;
+
+ QString _name,_url,_repos,_uuid,_copyfrom_url,_conflict_old,_conflict_new,_conflict_wrk,_prejfile,_checksum,_cmt_author;
+ bool _copied,_deleted,_absent,_incomplete;
+ svn_revnum_t _revision,_copyfrom_rev,_cmt_rev;
+ svn_node_kind_t _kind;
+ svn_wc_schedule_t _schedule;
+ DateTime _text_time,_prop_time,_cmt_date;
+
+ /**
+ * initializes the members
+ */
+ void
+ init (const svn_wc_entry_t * src);
+ void
+ init(const Entry_private&src);
+ void
+ init(const QString&url,const DirEntryPtr&src);
+ void
+ init(const QString&url,const InfoEntry&src);
+ };
+
+ void Entry_private::init_clean()
+ {
+ _name = _url = _repos = _uuid = _copyfrom_url = _conflict_old = _conflict_new = _conflict_wrk
+ = _prejfile = _checksum = _cmt_author = QString::null;
+ _revision = _copyfrom_rev = _cmt_rev = -1;
+ _kind = svn_node_unknown;
+ _schedule = svn_wc_schedule_normal;
+ _text_time = _prop_time = _cmt_date = 0;
+ _copied = _deleted = _absent = _incomplete = false;
+ }
+
+ Entry_private::Entry_private()
+ : m_valid (false),m_Lock()
+ {
+ init_clean();
+ }
+
+ Entry_private::Entry_private(const Entry_private&src)
+ : m_valid (false),m_Lock()
+ {
+ init_clean();
+ init(src);
+ }
+
+ Entry_private::~Entry_private()
+ {
+ }
+
+ void
+ Entry_private::init (const svn_wc_entry_t * src)
+ {
+ if (src) {
+ // copy & convert the contents of src
+ _name = QString::FROMUTF8(src->name);
+ _revision = src->revision;
+ _url = QString::FROMUTF8(src->url);
+ _repos = QString::FROMUTF8(src->repos);
+ _uuid = QString::FROMUTF8(src->uuid);
+ _kind = src->kind;
+ _schedule = src->schedule;
+ _copied = src->copied!=0;
+ _deleted = src->deleted!=0;
+ _absent = src->absent!=0;
+ _incomplete = src->incomplete!=0;
+ _copyfrom_url=QString::FROMUTF8(src->copyfrom_url);
+ _copyfrom_rev = src->copyfrom_rev;
+ _conflict_old = QString::FROMUTF8(src->conflict_old);
+ _conflict_new = QString::FROMUTF8(src->conflict_new);
+ _conflict_wrk = QString::FROMUTF8(src->conflict_wrk);
+ _prejfile = QString::FROMUTF8(src->prejfile);
+ _text_time = src->text_time;
+ _prop_time = src->prop_time;
+ _checksum = QString::FROMUTF8(src->checksum);
+ _cmt_rev = src->cmt_rev;
+ _cmt_date = src->cmt_date;
+ _cmt_author = QString::FROMUTF8(src->cmt_author);
+ m_Lock.init(src);
+ m_valid = true;
+ } else {
+ m_valid = false;
+ m_Lock=LockEntry();
+ _name=
+ _url=_repos=_uuid=_copyfrom_url=_conflict_old=_conflict_new=_conflict_wrk=_prejfile=_checksum=_cmt_author= QString::null;
+ _copied=_deleted=_absent=_incomplete = false;
+ _kind = svn_node_unknown;
+ _schedule=svn_wc_schedule_normal;
+ _text_time=_prop_time=_cmt_date=0;
+ }
+ }
+ void
+ Entry_private::init(const Entry_private&src)
+ {
+ _name=src._name;
+ _url=src._url;
+ _repos=src._repos;
+ _uuid=src._uuid;
+ _copyfrom_url=src._copyfrom_url;
+ _conflict_old=src._conflict_old;
+ _conflict_new=src._conflict_new;
+ _conflict_wrk=src._conflict_wrk;
+ _prejfile=src._prejfile;
+ _checksum=src._checksum;
+ _cmt_author=src._cmt_author;
+ _copied=src._copied;
+ _deleted=src._deleted;
+ _absent=src._absent;
+ _incomplete=src._incomplete;
+ _revision=src._revision;
+ _copyfrom_rev=src._copyfrom_rev;
+ _cmt_rev=src._cmt_rev;
+ _kind=src._kind;
+ _schedule=src._schedule;
+ _text_time=src._text_time;
+ _prop_time=src._prop_time;
+ _cmt_date=src._cmt_date;
+ _kind = src._kind;
+ m_Lock=src.m_Lock;
+ m_valid=src.m_valid;
+ }
+
+ void Entry_private::init(const QString&url,const DirEntryPtr&dirEntry)
+ {
+ init(0);
+ _url = url;
+ if (dirEntry) {
+ _name=dirEntry->name();
+ _revision = dirEntry->createdRev();
+ _kind = dirEntry->kind();
+ _schedule = svn_wc_schedule_normal;
+ _text_time = dirEntry->time ();
+ _prop_time = dirEntry->time ();
+ _cmt_rev = dirEntry->createdRev ();
+ _cmt_date = dirEntry->time ();
+ _cmt_author = dirEntry->lastAuthor ();
+ m_Lock=dirEntry->lockEntry();
+ m_valid = true;
+ }
+ }
+
+ void Entry_private::init(const QString&url,const InfoEntry&src)
+ {
+ init(0);
+ _name = src.Name();
+ _url = url;
+ _revision = src.revision();
+ _kind = src.kind ();
+ _schedule = svn_wc_schedule_normal;
+ _text_time = src.textTime ();
+ _prop_time = src.propTime ();
+ _cmt_rev = src.cmtRev ();
+ _cmt_date = src.cmtDate();
+ _cmt_author = src.cmtAuthor();
+ m_Lock=src.lockEntry();
+ m_valid = true;
+ }
+
+ Entry::Entry (const svn_wc_entry_t * src)
+ : m_Data(new Entry_private())
+ {
+ m_Data->init (src);
+ }
+
+ Entry::Entry (const Entry & src)
+ : m_Data(new Entry_private())
+ {
+ if (src.m_Data) {
+ m_Data->init(*(src.m_Data));
+ } else {
+ m_Data->init(0);
+ }
+ }
+
+ Entry::Entry (const QString&url,const DirEntryPtr&src)
+ : m_Data(new Entry_private())
+ {
+ m_Data->init(url,src);
+ }
+
+ Entry::Entry (const QString&url,const InfoEntry&src)
+ : m_Data(new Entry_private())
+ {
+ m_Data->init(url,src);
+ }
+
+ Entry::~Entry ()
+ {
+ delete m_Data;
+ }
+
+ Entry &
+ Entry::operator = (const Entry & src)
+ {
+ if (this == &src)
+ return *this;
+ if (src.m_Data) {
+ m_Data->init(*(src.m_Data));
+ } else {
+ m_Data->init(0);
+ }
+ return *this;
+ }
+
+ const LockEntry&
+ Entry::lockEntry()const
+ {
+ return m_Data->m_Lock;
+ }
+
+ const QString&
+ Entry::cmtAuthor () const
+ {
+ return m_Data->_cmt_author;
+ }
+
+ const DateTime&
+ Entry::cmtDate () const
+ {
+ return m_Data->_cmt_date;
+ }
+
+ svn_revnum_t
+ Entry::cmtRev () const
+ {
+ return m_Data->_cmt_rev;
+ }
+ const QString&
+ Entry::checksum () const
+ {
+ return m_Data->_checksum;
+ }
+
+ const DateTime&
+ Entry::propTime () const
+ {
+ return m_Data->_prop_time;
+ }
+
+ const DateTime&
+ Entry::textTime () const
+ {
+ return m_Data->_text_time;
+ }
+ const QString&
+ Entry::prejfile () const
+ {
+ return m_Data->_prejfile;
+ }
+ const QString&
+ Entry::conflictWrk () const
+ {
+ return m_Data->_conflict_wrk;
+ }
+
+ const QString&
+ Entry::conflictNew () const
+ {
+ return m_Data->_conflict_new;
+ }
+ const QString&
+ Entry::conflictOld () const
+ {
+ return m_Data->_conflict_old;
+ }
+ svn_revnum_t
+ Entry::copyfromRev () const
+ {
+ return m_Data->_copyfrom_rev;
+ }
+ const QString&
+ Entry::copyfromUrl () const
+ {
+ return m_Data->_copyfrom_url;
+ }
+
+ bool
+ Entry::isAbsent () const
+ {
+ return m_Data->_absent;
+ }
+ bool
+ Entry::isDeleted () const
+ {
+ return m_Data->_deleted != 0;
+ }
+ bool
+ Entry::isCopied () const
+ {
+ return m_Data->_copied != 0;
+ }
+ svn_wc_schedule_t
+ Entry::schedule () const
+ {
+ return m_Data->_schedule;
+ }
+ svn_node_kind_t
+ Entry::kind () const
+ {
+ return m_Data->_kind;
+ }
+ const QString&
+ Entry::uuid () const
+ {
+ return m_Data->_uuid;
+ }
+ const QString&
+ Entry::repos () const
+ {
+ return m_Data->_repos;
+ }
+ const QString&
+ Entry::url () const
+ {
+ return m_Data->_url;
+ }
+ svn_revnum_t
+ Entry::revision () const
+ {
+ return m_Data->_revision;
+ }
+ const QString&
+ Entry::name () const
+ {
+ return m_Data->_name;
+ }
+
+ bool Entry::isValid () const
+ {
+ return m_Data->m_valid;
+ }
+}
+
+/*!
+ \fn svn::Entry::isDir()
+ */
+bool svn::Entry::isDir() const
+{
+ return kind()==svn_node_dir;
+}
+
+
+/*!
+ \fn svn::Entry::isFile()
+ */
+bool svn::Entry::isFile() const
+{
+ return kind()==svn_node_file;
+}
diff --git a/src/svnqt/entry.hpp b/src/svnqt/entry.hpp
new file mode 100644
index 0000000..0043622
--- /dev/null
+++ b/src/svnqt/entry.hpp
@@ -0,0 +1,245 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#ifndef _SVNCPP_ENTRY_HPP_
+#define _SVNCPP_ENTRY_HPP_
+
+// svncpp
+#include "svnqt/pool.hpp"
+#include "svnqt/lock_entry.hpp"
+#include "svnqt/dirent.hpp"
+#include "svnqt/info_entry.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/svnqttypes.hpp"
+
+// subversion api
+#include "svn_wc.h"
+
+
+#include <qstring.h>
+
+namespace svn
+{
+ class Entry_private;
+ /**
+ * C++ API for Subversion.
+ * This class wraps around @a svn_wc_entry_t.
+ */
+ class SVNQT_EXPORT Entry
+ {
+ public:
+ /**
+ * default constructor. if @a src is set,
+ * copy its contents.
+ *
+ * If @a src is not set (=0) this will be
+ * a non-versioned entry. This can be checked
+ * later with @a isValid ().
+ *
+ * @param src another entry to copy from
+ */
+ Entry (const svn_wc_entry_t * src = 0);
+
+ /**
+ * copy constructor
+ */
+ Entry (const Entry & src);
+
+ /**
+ * converting constructr
+ */
+ Entry (const QString&url,const DirEntryPtr&src);
+ /**
+ * converting constructr
+ */
+ Entry (const QString&url,const InfoEntry&src);
+
+ /**
+ * destructor
+ */
+ virtual ~Entry ();
+
+ /**
+ * returns whether this is a valid=versioned
+ * entry.
+ *
+ * @return is entry valid
+ * @retval true valid entry
+ * @retval false invalid or unversioned entry
+ */
+ bool isValid () const;
+ /**
+ * @return entry's name
+ */
+ const QString&
+ name () const;
+ /**
+ * @return base revision
+ */
+ svn_revnum_t
+ revision () const;
+ /**
+ * @return url in repository
+ */
+ const QString&
+ url () const;
+
+ /**
+ * @return canonical repository url
+ */
+ const QString&
+ repos () const;
+ /**
+ * @return repository uuid
+ */
+ const QString&
+ uuid () const;
+ /**
+ * @return node kind (file, dir, ...)
+ */
+ svn_node_kind_t
+ kind () const;
+ /**
+ * @return scheduling (add, delete, replace)
+ */
+ svn_wc_schedule_t
+ schedule () const;
+ /**
+ * @return TRUE if copied
+ */
+ bool
+ isCopied () const;
+ /**
+ * @return true if deleted
+ */
+ bool
+ isDeleted () const;
+ /**
+ * @return true if deleted
+ */
+ bool
+ isAbsent () const;
+ /**
+ * @return copyfrom location
+ */
+ const QString&
+ copyfromUrl () const;
+ /**
+ * @return copyfrom revision
+ */
+ svn_revnum_t
+ copyfromRev () const;
+ /**
+ * @return old version of conflicted file
+ */
+ const QString&
+ conflictOld () const;
+ /**
+ * @return new version of conflicted file
+ */
+ const QString&
+ conflictNew () const;
+ /**
+ * @return working version of conflicted file
+ */
+ const QString&
+ conflictWrk () const;
+ /**
+ * @return property reject file
+ */
+ const QString&
+ prejfile () const;
+ /**
+ * @return last up-to-date time for text contents
+ * @retval 0 no information available
+ */
+ const DateTime&
+ textTime () const;
+ /**
+ * @return last up-to-date time for properties
+ * @retval 0 no information available
+ */
+ const DateTime&
+ propTime()const;
+
+ /**
+ * @return base64 encoded checksum
+ * @retval NULL for backwards compatibility
+ */
+ const QString&
+ checksum () const;
+
+ /**
+ * @return last revision this was changed
+ */
+ svn_revnum_t
+ cmtRev () const;
+
+ /**
+ * @return last date this was changed
+ */
+ const DateTime&
+ cmtDate () const;
+
+ /**
+ * @return last commit author of this file
+ */
+ const QString&
+ cmtAuthor () const;
+
+ /**
+ * @return lock for that entry
+ * @since subversion 1.2
+ */
+ const LockEntry&
+ lockEntry()const;
+
+ /**
+ * @return true if entry is marked as dir
+ */
+ bool isDir()const;
+ /**
+ * assignment operator
+ */
+ Entry &
+ operator = (const Entry &);
+ bool isFile()const;
+
+ private:
+ Entry_private*m_Data;
+ };
+
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/exception.cpp b/src/svnqt/exception.cpp
new file mode 100644
index 0000000..67bcb60
--- /dev/null
+++ b/src/svnqt/exception.cpp
@@ -0,0 +1,224 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+
+// svncpp
+#include "exception.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qstring.h>
+
+#ifdef HAS_BACKTRACE_H
+#include <execinfo.h>
+#include <qstringlist.h>
+#define SVNQT_BACKTRACE_LENGTH 20
+#endif
+
+namespace svn
+{
+
+ struct Exception::Data
+ {
+ private:
+ public:
+ QString message;
+ apr_status_t apr_err;
+
+ Data (const char * msg)
+ : message(QString::FROMUTF8(msg)),apr_err(0)
+ {
+ }
+
+ Data (const QString& msg)
+ : message(msg),apr_err(0)
+ {
+ }
+
+
+ Data (const Data& other)
+ : message(other.message), apr_err(other.apr_err)
+ {
+ }
+ };
+
+ Exception::Exception (const char * message) throw ()
+ {
+ m = new Data (message);
+ }
+
+ Exception::Exception (const QString& message) throw ()
+ {
+ m = new Data (message);
+ }
+
+ Exception::Exception (const Exception & other) throw ()
+ {
+ m = new Data (*other.m);
+ }
+
+ Exception::~Exception () throw ()
+ {
+ delete m;
+ }
+
+ apr_status_t
+ Exception::apr_err () const
+ {
+ return m->apr_err;
+ }
+
+ const QString&
+ Exception::msg () const
+ {
+ return m->message;
+ }
+
+ void Exception::setMessage(const QString&aMsg)
+ {
+ m->message=aMsg;
+ }
+
+ QString Exception::error2msg(svn_error_t*error)
+ {
+ QString message = "";
+ if (error==0) {
+ return message;
+ }
+ svn_error_t * next = error->child;
+ if (error->message)
+ message = QString::FROMUTF8(error->message);
+ else
+ {
+ message = "Unknown error!\n";
+ if (error->file)
+ {
+ message += QString::FROMUTF8("In file ");
+ message += QString::FROMUTF8(error->file);
+ message += QString(" Line %1").arg(error->line);
+ }
+ }
+ while (next != NULL && next->message != NULL)
+ {
+ message = message + "\n" + QString::FROMUTF8(next->message);
+
+ next = next->child;
+ }
+
+ return message;
+
+ }
+
+ ClientException::ClientException (const char*msg) throw ()
+ : Exception (msg)
+ {
+ }
+
+ ClientException::ClientException (const QString&msg) throw ()
+ : Exception (msg)
+ {
+ }
+
+ ClientException::ClientException (svn_error_t * error) throw ()
+ : Exception ("")
+ {
+ init();
+ if (error == 0)
+ return;
+
+ m->apr_err = error->apr_err;
+ m->message += error2msg(error);
+ svn_error_clear (error);
+ }
+
+ ClientException::ClientException (apr_status_t status) throw ()
+ : Exception ("")
+ {
+ init();
+ m->apr_err = status;
+ }
+
+
+ ClientException::~ClientException () throw ()
+ {
+ }
+
+ ClientException::ClientException (const ClientException & src) throw ()
+ : Exception (src.msg())
+ {
+ m->apr_err = src.apr_err();
+ }
+
+ void ClientException::init()
+ {
+#ifdef USEBACKTRACE
+ if (m_backTraceConstr.length()==0) {
+ m_backTraceConstr = getBackTrace();
+ m->message=m_backTraceConstr;
+ }
+#else
+ m_backTraceConstr="";
+#endif
+ }
+
+ QString ClientException::getBackTrace()
+ {
+ QString Result;
+ qDebug("getBackTrace");
+#ifdef HAS_BACKTRACE_H
+ qDebug("Generating backtrace");
+ void *array[SVNQT_BACKTRACE_LENGTH];
+ size_t size;
+ size_t i;
+
+ size = backtrace (array, SVNQT_BACKTRACE_LENGTH);
+ if (!size) {
+ return Result;
+ }
+
+ char ** strings = backtrace_symbols (array, size);
+
+ QStringList r;
+ for (i = 0; i < size; ++i) {
+ r.push_back(QString::number(i) +
+ QString::FROMUTF8(": ") +
+ QString::FROMUTF8(strings[i]));
+ }
+ Result = QString::FROMUTF8("[\n")+r.join("\n")+QString::FROMUTF8("]\n");
+ free (strings);
+#endif
+ return Result;
+ }
+
+}
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/exception.hpp b/src/svnqt/exception.hpp
new file mode 100644
index 0000000..b83269f
--- /dev/null
+++ b/src/svnqt/exception.hpp
@@ -0,0 +1,138 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_EXCEPTION_H_
+#define _SVNCPP_EXCEPTION_H_
+
+#include "svnqt/svnqt_defines.hpp"
+// subversion api
+#include "svn_client.h"
+#include <qstring.h>
+
+namespace svn
+{
+
+ /**
+ * Generic exception class.
+ */
+ class SVNQT_EXPORT Exception
+ {
+ public:
+ /**
+ * Constructor. Assigns the exception reason.
+ */
+ Exception (const char * message) throw ();
+ Exception (const QString&message) throw();
+
+ virtual ~Exception () throw ();
+
+ /**
+ * @return the exception message.
+ */
+ virtual const QString& msg() const;
+
+ /**
+ * @return the outermost error code.
+ */
+ apr_status_t apr_err () const;
+
+ static QString error2msg(svn_error_t*error);
+
+ protected:
+ struct Data;
+ Data * m;
+ void setMessage(const QString&);
+
+ private:
+
+ Exception (const Exception &) throw ();
+
+ Exception () throw ();
+
+ Exception & operator = (const Exception &);
+
+ };
+
+ /**
+ * Subversion client exception class.
+ */
+ class SVNQT_EXPORT ClientException : public Exception
+ {
+ public:
+ /**
+ * Constructor. Sets the error template and an optional message.
+ * @param error the error to display. This will get cleared inside with svn_error_clear
+ * so it isn't usable after that!
+ */
+ ClientException (svn_error_t * error) throw ();
+
+
+ /**
+ * Constructor that takes only an apr errorcode
+ */
+ ClientException (apr_status_t status) throw ();
+
+ /**
+ * Constructor
+ */
+ ClientException (const char*msg) throw ();
+
+ /**
+ * Constructor
+ */
+ ClientException (const QString&message) throw();
+
+ /**
+ * Copy constructor
+ */
+ ClientException (const ClientException & src) throw ();
+
+ virtual ~ClientException () throw ();
+
+ private:
+ ClientException () throw ();
+
+ ClientException & operator = (ClientException &);
+ static QString getBackTrace();
+
+ void init();
+ /// backtrace from constructor;
+ QString m_backTraceConstr;
+
+ };
+
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/helper.hpp b/src/svnqt/helper.hpp
new file mode 100644
index 0000000..fca54d1
--- /dev/null
+++ b/src/svnqt/helper.hpp
@@ -0,0 +1,98 @@
+
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef __HELPER_HPP
+#define __HELPER_HPP
+
+#include "svnqttypes.hpp"
+#include "revision.hpp"
+#include <svn_types.h>
+
+#include <iostream>
+
+namespace svn
+{
+ namespace internal
+ {
+ class DepthToSvn
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ protected:
+ svn_depth_t _value;
+ public:
+ DepthToSvn(const svn::Depth&val):_value(svn_depth_unknown)
+ {
+ switch (val) {
+ case DepthUnknown:
+ _value = svn_depth_unknown;
+ break;
+ case DepthExclude:
+ _value = svn_depth_exclude;
+ break;
+ case DepthEmpty:
+ _value = svn_depth_empty;
+ break;
+ case DepthFiles:
+ _value = svn_depth_files;
+ break;
+ case DepthImmediates:
+ _value = svn_depth_immediates;
+ break;
+ case DepthInfinity:
+ default:
+ _value = svn_depth_infinity;
+ break;
+ }
+ }
+
+ operator svn_depth_t ()
+ {
+ return _value;
+ }
+#endif
+ };
+
+ class RevisionRangesToHash
+ {
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ protected:
+ RevisionRanges m_ranges;
+ public:
+ RevisionRangesToHash(const RevisionRanges&_input):m_ranges(_input){}
+
+ apr_array_header_t*array(const Pool&pool)
+ {
+ apr_array_header_t*ranges=apr_array_make(pool,m_ranges.size(),sizeof(svn_opt_revision_range_t *));
+ svn_opt_revision_range_t *range;
+
+ for (unsigned long j=0;j<m_ranges.count();++j)
+ {
+ range = (svn_opt_revision_range_t *)apr_palloc(pool, sizeof(*range));
+ range->start= *m_ranges[j].first.revision();
+ range->end = *m_ranges[j].second.revision();
+ APR_ARRAY_PUSH(ranges,svn_opt_revision_range_t *) = range;
+ }
+ return ranges;
+ }
+#endif
+ };
+ }
+}
+#endif
diff --git a/src/svnqt/info_entry.cpp b/src/svnqt/info_entry.cpp
new file mode 100644
index 0000000..72d714a
--- /dev/null
+++ b/src/svnqt/info_entry.cpp
@@ -0,0 +1,311 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "svnqt/info_entry.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/pool.hpp"
+#include <svn_client.h>
+#include <svn_path.h>
+
+namespace svn
+{
+
+ InfoEntry::InfoEntry()
+ {
+ init();
+ }
+
+ InfoEntry::InfoEntry(const svn_info_t*info,const char*path)
+ {
+ init(info,path);
+ }
+
+ InfoEntry::InfoEntry(const svn_info_t*info,const QString&path)
+ {
+ init(info,path);
+ }
+
+ InfoEntry::~InfoEntry()
+ {
+ }
+
+ DateTime InfoEntry::cmtDate()const
+ {
+ return m_last_changed_date;
+ }
+ DateTime InfoEntry::textTime()const
+ {
+ return m_text_time;
+ }
+ DateTime InfoEntry::propTime()const
+ {
+ return m_prop_time;
+ }
+ bool InfoEntry::hasWc()const
+ {
+ return m_hasWc;
+ }
+ const LockEntry&InfoEntry::lockEntry()const
+ {
+ return m_Lock;
+ }
+ const QString&InfoEntry::cmtAuthor () const
+ {
+ return m_last_author;
+ }
+ const QString&InfoEntry::Name()const
+ {
+ return m_name;
+ }
+ const QString& InfoEntry::checksum()const
+ {
+ return m_checksum;
+ }
+ const QString& InfoEntry::conflictNew()const
+ {
+ return m_conflict_new;
+ }
+ const QString& InfoEntry::conflictOld()const
+ {
+ return m_conflict_old;
+ }
+ const QString& InfoEntry::conflictWrk()const
+ {
+ return m_conflict_wrk;
+ }
+ const QString& InfoEntry::copyfromUrl()const
+ {
+ return m_copyfrom_url;
+ }
+ const QString& InfoEntry::prejfile()const
+ {
+ return m_prejfile;
+ }
+ const QString& InfoEntry::reposRoot()const
+ {
+ return m_repos_root;
+ }
+ const QString& InfoEntry::url()const
+ {
+ return m_url;
+ }
+ const QString& InfoEntry::uuid()const
+ {
+ return m_UUID;
+ }
+ svn_node_kind_t InfoEntry::kind()const
+ {
+ return m_kind;
+ }
+ const Revision& InfoEntry::cmtRev()const
+ {
+ return m_last_changed_rev;
+ }
+ const Revision& InfoEntry::copyfromRev()const
+ {
+ return m_copy_from_rev;
+ }
+ const Revision& InfoEntry::revision()const
+ {
+ return m_revision;
+ }
+ svn_wc_schedule_t InfoEntry::Schedule()const
+ {
+ return m_schedule;
+ }
+ const QString&InfoEntry::prettyUrl()const
+ {
+ return m_pUrl;
+ }
+ bool InfoEntry::isDir()const
+ {
+ return kind()==svn_node_dir;
+ }
+ const QByteArray&InfoEntry::changeList()const
+ {
+ return m_changeList;
+ }
+ QLONG InfoEntry::size()const
+ {
+ return m_size;
+ }
+ QLONG InfoEntry::working_size()const
+ {
+ return m_working_size;
+ }
+ svn::Depth InfoEntry::depth()const
+ {
+ return m_depth;
+ }
+}
+
+/*!
+ \fn svn::InfoEntry::init()
+ */
+void svn::InfoEntry::init()
+{
+ m_name = "";
+ m_last_changed_date=0;
+ m_text_time = 0;
+ m_prop_time = 0;
+ m_hasWc = false;
+ m_Lock = LockEntry();
+ m_checksum = "";
+ m_conflict_new = "";
+ m_conflict_old = "";
+ m_conflict_wrk = "";
+ m_copyfrom_url = "";
+ m_last_author = "";
+ m_prejfile = "";
+ m_repos_root = "";
+ m_url = "";
+ m_pUrl = "";
+ m_UUID = "";
+ m_kind = svn_node_none;
+ m_copy_from_rev = SVN_INVALID_REVNUM;
+ m_last_changed_rev = SVN_INVALID_REVNUM;
+ m_revision = SVN_INVALID_REVNUM;
+ m_schedule = svn_wc_schedule_normal;
+
+ m_size = m_working_size = SVNQT_SIZE_UNKNOWN;
+ m_changeList=QByteArray();
+ m_depth = DepthUnknown;
+}
+
+void svn::InfoEntry::init(const svn_info_t*item,const char*path)
+{
+ init(item,QString::FROMUTF8(path));
+}
+
+/*!
+ \fn svn::InfoEntry::init(const svn_info_t*)
+ */
+void svn::InfoEntry::init(const svn_info_t*item,const QString&path)
+{
+ if (!item) {
+ init();
+ return;
+ }
+ m_name = path;
+ m_last_changed_date=item->last_changed_date;
+ m_text_time = item->text_time;
+ m_prop_time = item->prop_time;
+ if (item->lock) {
+ m_Lock.init(item->lock);
+ } else {
+ m_Lock = LockEntry();
+ }
+ m_checksum = QString::FROMUTF8(item->checksum);
+ m_conflict_new = QString::FROMUTF8(item->conflict_new);
+ m_conflict_old = QString::FROMUTF8(item->conflict_old);
+ m_conflict_wrk = QString::FROMUTF8(item->conflict_wrk);
+ m_copyfrom_url = QString::FROMUTF8(item->copyfrom_url);
+ m_last_author = QString::FROMUTF8(item->last_changed_author);
+ m_prejfile = QString::FROMUTF8(item->prejfile);
+ m_repos_root = QString::FROMUTF8(item->repos_root_URL);
+ m_url = QString::FROMUTF8(item->URL);
+ m_pUrl = prettyUrl(item->URL);
+ m_UUID = QString::FROMUTF8(item->repos_UUID);
+ m_kind = item->kind;
+ m_copy_from_rev = item->copyfrom_rev;
+ m_last_changed_rev = item->last_changed_rev;
+ m_revision = item->rev;
+ m_hasWc = item->has_wc_info;
+ m_schedule = item->schedule;
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ m_size = item->size!=SVN_INFO_SIZE_UNKNOWN?QLONG(item->size):SVNQT_SIZE_UNKNOWN;
+ m_working_size = item->working_size!=SVN_INFO_SIZE_UNKNOWN?QLONG(item->working_size):SVNQT_SIZE_UNKNOWN;
+ if (item->changelist) {
+#if QT_VERSION < 0x040000
+ m_changeList = QByteArray(QCString(item->changelist,strlen(item->changelist)));
+#else
+ m_changeList = QByteArray(item->changelist,strlen(item->changelist));
+#endif
+ } else {
+ m_changeList=QByteArray();
+ }
+
+ switch (item->depth) {
+ case svn_depth_exclude:
+ m_depth=DepthExclude;
+ break;
+ case svn_depth_empty:
+ m_depth=DepthEmpty;
+ break;
+ case svn_depth_files:
+ m_depth=DepthFiles;
+ break;
+ case svn_depth_immediates:
+ m_depth=DepthImmediates;
+ break;
+ case svn_depth_infinity:
+ m_depth=DepthInfinity;
+ break;
+ case svn_depth_unknown:
+ default:
+ m_depth=DepthUnknown;
+ break;
+ }
+#else
+ m_size = SVNQT_SIZE_UNKNOWN;
+ m_working_size = SVNQT_SIZE_UNKNOWN;
+ m_changeList=QByteArray();
+ m_depth = DepthUnknown;
+#endif
+}
+
+QString svn::InfoEntry::prettyUrl(const char*_url)const
+{
+ if (_url) {
+ Pool pool;
+ _url = svn_path_uri_decode(_url,pool);
+ return QString::FROMUTF8(_url);
+ }
+ return QString::FROMUTF8("");
+}
+
+svn::InfoEntry::InfoEntry(const InfoEntry&other)
+{
+ m_name = other.m_name;
+ m_last_changed_date=other.m_last_changed_date;
+ m_text_time = other.m_text_time;
+ m_prop_time = other.m_prop_time;
+ m_Lock = other.m_Lock;
+ m_checksum = other.m_checksum;
+ m_conflict_new = other.m_conflict_new;
+ m_conflict_old = other.m_conflict_old;
+ m_conflict_wrk = other.m_conflict_wrk;
+ m_copyfrom_url = other.m_copyfrom_url;
+ m_last_author = other.m_last_author;
+ m_prejfile = other.m_prejfile;
+ m_repos_root = other.m_repos_root;
+ m_url = other.m_url;
+ m_pUrl = other.m_pUrl;
+ m_UUID = other.m_UUID;
+ m_kind = other.m_kind;
+ m_copy_from_rev = other.m_copy_from_rev;
+ m_last_changed_rev = other.m_last_changed_rev;
+ m_revision = other.m_revision;
+ m_hasWc = other.m_hasWc;
+ m_schedule = other.m_schedule;
+ m_size = other.m_size;
+ m_working_size = other.m_working_size;
+
+}
diff --git a/src/svnqt/info_entry.hpp b/src/svnqt/info_entry.hpp
new file mode 100644
index 0000000..91de95c
--- /dev/null
+++ b/src/svnqt/info_entry.hpp
@@ -0,0 +1,118 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef __INFO_ENTRY_H
+#define __INFO_ENTRY_H
+
+#include <svnqt/lock_entry.hpp>
+#include <svnqt/datetime.hpp>
+#include <svnqt/revision.hpp>
+#include <svnqt/svnqttypes.hpp>
+
+#include <qstring.h>
+
+struct svn_info_t;
+
+namespace svn {
+ class SVNQT_EXPORT InfoEntry
+ {
+public:
+ InfoEntry();
+ InfoEntry(const svn_info_t*,const char*path);
+ InfoEntry(const svn_info_t*,const QString&path);
+ InfoEntry(const InfoEntry&);
+ ~InfoEntry();
+
+ void init(const svn_info_t*,const char*path);
+ void init(const svn_info_t*,const QString&path);
+
+ DateTime cmtDate()const;
+ DateTime textTime()const;
+ DateTime propTime()const;
+ bool hasWc()const;
+ /**
+ * @return lock for that entry
+ * @since subversion 1.2
+ */
+ const LockEntry&lockEntry()const;
+ /**
+ * @return last commit author of this file
+ */
+ const QString&cmtAuthor () const;
+ const QString&Name()const;
+
+ const QString& checksum()const;
+ const QString& conflictNew()const;
+ const QString& conflictOld()const;
+ const QString& conflictWrk()const;
+ const QString& copyfromUrl()const;
+ const QString& prejfile()const;
+ const QString& reposRoot()const;
+ const QString& url()const;
+ const QString& uuid()const;
+ svn_node_kind_t kind()const;
+ const Revision& cmtRev()const;
+ const Revision& copyfromRev()const;
+ const Revision& revision()const;
+ svn_wc_schedule_t Schedule()const;
+
+ QLONG size()const;
+ QLONG working_size()const;
+ const QByteArray&changeList()const;
+ svn::Depth depth()const;
+
+ const QString&prettyUrl()const;
+
+ bool isDir()const;
+ QString prettyUrl(const char*)const;
+
+protected:
+ DateTime m_last_changed_date;
+ DateTime m_text_time;
+ DateTime m_prop_time;
+ bool m_hasWc;
+ LockEntry m_Lock;
+ QString m_name;
+ QString m_checksum;
+ QString m_conflict_new;
+ QString m_conflict_old;
+ QString m_conflict_wrk;
+ QString m_copyfrom_url;
+ QString m_last_author;
+ QString m_prejfile;
+ QString m_repos_root;
+ QString m_url;
+ QString m_pUrl;
+ QString m_UUID;
+ svn_node_kind_t m_kind;
+ Revision m_copy_from_rev;
+ Revision m_last_changed_rev;
+ Revision m_revision;
+ svn_wc_schedule_t m_schedule;
+
+ QLONG m_size;
+ QLONG m_working_size;
+ QByteArray m_changeList;
+ svn::Depth m_depth;
+
+protected:
+ void init();
+ };
+}
+#endif
diff --git a/src/svnqt/lock_entry.cpp b/src/svnqt/lock_entry.cpp
new file mode 100644
index 0000000..cf7ffe1
--- /dev/null
+++ b/src/svnqt/lock_entry.cpp
@@ -0,0 +1,141 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// svncpp
+#include "lock_entry.hpp"
+#include "pool.hpp"
+
+// subversion api
+#include "svn_time.h"
+#include "svn_version.h"
+
+
+namespace svn
+{
+ LockEntry::LockEntry ()
+ : date(0),exp(0),owner(""),comment(""),token(""),locked(false)
+ {
+ }
+
+ LockEntry::LockEntry (
+ const apr_time_t lock_time,
+ const apr_time_t expiration_time,
+ const char * lock_owner,
+ const char * lock_comment,
+ const char * lock_token)
+ : date(lock_time),exp(expiration_time),
+ owner(lock_owner?QString::FROMUTF8(lock_owner):""),
+ comment(lock_comment?QString::FROMUTF8(lock_comment):""),
+ token(lock_token?QString::FROMUTF8(lock_token):""),
+ locked(lock_token?true:false)
+ {
+ }
+ const QString&LockEntry::Comment()const
+ {
+ return comment;
+ }
+ const QString&LockEntry::Owner()const
+ {
+ return owner;
+ }
+ const QString&LockEntry::Token()const
+ {
+ return token;
+ }
+ const DateTime&LockEntry::Date()const
+ {
+ return date;
+ }
+ const DateTime&LockEntry::Expiration()const
+ {
+ return exp;
+ }
+ bool LockEntry::Locked()const
+ {
+ return locked;
+ }
+ void LockEntry::init(const svn_wc_entry_t * src)
+ {
+ if (src) {
+ date = src->lock_creation_date;
+ locked = src->lock_token?true:false;
+ token = (src->lock_token?QString::FROMUTF8(src->lock_token):"");
+ comment = (src->lock_comment?QString::FROMUTF8(src->lock_comment):"");
+ owner = (src->lock_owner?QString::FROMUTF8(src->lock_owner):"");
+ } else {
+ date = 0;
+ owner = "";
+ comment = "";
+ token = "";
+ locked = false;
+ }
+ exp = 0;
+ }
+
+ void LockEntry::init(const svn_lock_t* src)
+ {
+ if (src) {
+ date = src->creation_date;
+ locked = src->token?true:false;
+ token = (src->token?QString::FROMUTF8(src->token):"");
+ comment = (src->comment?QString::FROMUTF8(src->comment):"");
+ owner = (src->owner?QString::FROMUTF8(src->owner):"");
+ } else {
+ date = 0;
+ exp = 0;
+ owner = "";
+ comment = "";
+ token = "";
+ locked = false;
+ }
+
+ }
+
+ void LockEntry::init(
+ const apr_time_t lock_time,
+ const apr_time_t expiration_time,
+ const char * lock_owner,
+ const char * lock_comment,
+ const char * lock_token)
+ {
+ date = lock_time;
+ exp = expiration_time;
+ locked = lock_token?true:false;
+ token = lock_token?QString::FROMUTF8(lock_token):"";
+ owner = lock_owner?QString::FROMUTF8(lock_owner):"";
+ comment = lock_comment?QString::FROMUTF8(lock_comment):"";
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/lock_entry.hpp b/src/svnqt/lock_entry.hpp
new file mode 100644
index 0000000..eec3d1f
--- /dev/null
+++ b/src/svnqt/lock_entry.hpp
@@ -0,0 +1,90 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_LOCK_ENTRY_H_
+#define _SVNCPP_LOCK_ENTRY_H_
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/datetime.hpp"
+
+#include <qstring.h>
+
+// apr
+#include "apr_time.h"
+
+// subversion api
+#include "svn_types.h"
+#include "svn_wc.h"
+
+namespace svn
+{
+ class SVNQT_EXPORT LockEntry
+ {
+ public:
+ LockEntry ();
+
+ LockEntry (const apr_time_t lock_time,
+ const apr_time_t expiration_time,
+ const char * lock_owner,
+ const char * lock_comment,
+ const char * lock_token);
+
+ void init(const svn_wc_entry_t * src);
+
+ void init(const apr_time_t lock_time,
+ const apr_time_t expiration_time,
+ const char * lock_owner,
+ const char * lock_comment,
+ const char * lock_token);
+ void init(const svn_lock_t*);
+ const QString&Comment()const;
+ const QString&Owner()const;
+ const QString&Token()const;
+ const DateTime&Date()const;
+ const DateTime&Expiration()const;
+ bool Locked()const;
+
+ protected:
+ DateTime date;
+ DateTime exp;
+ QString owner;
+ QString comment;
+ QString token;
+ bool locked;
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
+
diff --git a/src/svnqt/log_entry.cpp b/src/svnqt/log_entry.cpp
new file mode 100644
index 0000000..fdd28e8
--- /dev/null
+++ b/src/svnqt/log_entry.cpp
@@ -0,0 +1,190 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+// svncpp
+#include "log_entry.hpp"
+#include "pool.hpp"
+
+// subversion api
+#include "svn_time.h"
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+#include "svn_compat.h"
+#endif
+
+
+namespace svn
+{
+ LogChangePathEntry::LogChangePathEntry (
+ const char *path_,
+ char action_,
+ const char *copyFromPath_,
+ const svn_revnum_t copyFromRevision_)
+ : path(QString::FROMUTF8(path_)), action(action_),
+ copyFromPath (QString::FROMUTF8(copyFromPath_)),
+ copyFromRevision (copyFromRevision_)
+ {
+ }
+
+ LogChangePathEntry::LogChangePathEntry (const QString &path_,
+ char action_,
+ const QString &copyFromPath_,
+ const svn_revnum_t copyFromRevision_)
+ : path(path_),
+ action(action_),
+ copyFromPath(copyFromPath_),
+ copyToPath(QString::null),
+ copyFromRevision(copyFromRevision_),
+ copyToRevision(-1)
+ {
+ }
+
+ LogChangePathEntry::LogChangePathEntry()
+ : path(QString::null),action(0),copyFromPath(QString::null),copyToPath(QString::null),
+ copyFromRevision(-1),copyToRevision(-1)
+ {
+ }
+
+ LogChangePathEntry::LogChangePathEntry (const QString &path_,
+ char action_,
+ const QString &copyFromPath_,
+ const svn_revnum_t copyFromRevision_,
+ const QString &copyToPath_,
+ const svn_revnum_t copyToRevision_)
+ : path(path_),action(action_),copyFromPath(copyFromPath_),copyToPath(copyToPath_),
+ copyFromRevision(copyFromRevision_),copyToRevision(copyToRevision_)
+ {
+ }
+
+ LogEntry::LogEntry ()
+ : revision(-1),date(0),author(""),message("")
+ {
+ }
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ LogEntry::LogEntry(svn_log_entry_t*log_entry)
+ : revision(-1),date(0),author(""),message("")
+ {
+ Pool pool;
+ const char *author_;
+ const char *date_;
+ const char *message_;
+ svn_compat_log_revprops_out(&author_, &date_, &message_, log_entry->revprops);
+
+ author = author_ == 0 ? QString::fromLatin1("") : QString::FROMUTF8(author_);
+ message = message_ == 0 ? QString::fromLatin1("") : QString::FROMUTF8(message_);
+ setDate(date_);
+ revision = log_entry->revision;
+ if (log_entry->changed_paths) {
+ for (apr_hash_index_t *hi = apr_hash_first (pool, log_entry->changed_paths);
+ hi != NULL;
+ hi = apr_hash_next (hi))
+ {
+ const void *pv;
+ void *val;
+ apr_hash_this (hi, &pv, NULL, &val);
+ svn_log_changed_path_t *log_item = reinterpret_cast<svn_log_changed_path_t *> (val);
+ const char* path = reinterpret_cast<const char*>(pv);
+ changedPaths.push_back (LogChangePathEntry (path,log_item->action,log_item->copyfrom_path,log_item->copyfrom_rev) );
+ }
+ }
+ }
+#endif
+
+ LogEntry::LogEntry (
+ const svn_revnum_t revision_,
+ const char * author_,
+ const char * date_,
+ const char * message_)
+ {
+ setDate(date_);
+
+ revision = revision_;
+ author = author_ == 0 ? QString::fromLatin1("") : QString::FROMUTF8(author_);
+ message = message_ == 0 ? QString::fromLatin1("") : QString::FROMUTF8(message_);
+ }
+
+ void LogEntry::setDate(const char*date_)
+ {
+ apr_time_t date__ = 0;
+ if (date_ != 0)
+ {
+ Pool pool;
+
+ if (svn_time_from_cstring (&date__, date_, pool) != 0)
+ date__ = 0;
+ }
+ date = date__;
+ }
+}
+
+
+SVNQT_EXPORT QDataStream& operator<<(QDataStream&s,const svn::LogEntry&r)
+{
+ s << r.revision
+ << r.author
+ << r.message
+ << r.changedPaths
+ << r.date;
+ return s;
+}
+
+SVNQT_EXPORT QDataStream& operator<<(QDataStream&s,const svn::LogChangePathEntry&r)
+{
+ short ac = r.action;
+ s << r.path
+ << ac
+ << r.copyFromPath
+ << r.copyFromRevision
+ << r.copyToPath
+ << r.copyToRevision;
+ return s;
+}
+
+SVNQT_EXPORT QDataStream& operator>>(QDataStream&s,svn::LogEntry&r)
+{
+ s >> r.revision
+ >> r.author
+ >> r.message
+ >> r.changedPaths
+ >> r.date;
+ return s;
+}
+
+SVNQT_EXPORT QDataStream& operator>>(QDataStream&s,svn::LogChangePathEntry&r)
+{
+ short ac;
+ s >> r.path
+ >> ac
+ >> r.copyFromPath
+ >> r.copyFromRevision
+ >> r.copyToPath
+ >> r.copyToRevision;
+ r.action = ac;
+ return s;
+}
diff --git a/src/svnqt/log_entry.hpp b/src/svnqt/log_entry.hpp
new file mode 100644
index 0000000..cc33f60
--- /dev/null
+++ b/src/svnqt/log_entry.hpp
@@ -0,0 +1,137 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_LOG_ENTRY_H_
+#define _SVNCPP_LOG_ENTRY_H_
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/datetime.hpp"
+
+//Qt
+#include <qglobal.h>
+
+#if QT_VERSION < 0x040000
+
+#include <qglobal.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+#include <qmap.h>
+
+#else
+
+#include <QtCore>
+
+#endif
+
+// apr
+#include "apr_time.h"
+
+// subversion api
+#include "svn_types.h"
+#include "svn_version.h"
+
+namespace svn
+{
+
+ class SVNQT_EXPORT LogChangePathEntry
+ {
+ public:
+ LogChangePathEntry (const char *path_,
+ char action_,
+ const char *copyFromPath_,
+ const svn_revnum_t copyFromRevision_);
+
+ LogChangePathEntry (const QString &path_,
+ char action_,
+ const QString &copyFromPath_,
+ const svn_revnum_t copyFromRevision_);
+
+ LogChangePathEntry (const QString &path_,
+ char action_,
+ const QString &copyFromPath_,
+ const svn_revnum_t copyFromRevision_,
+ const QString &copyToPath_,
+ const svn_revnum_t copyToRevision_);
+
+ LogChangePathEntry();
+
+ QString path;
+ char action;
+ QString copyFromPath;
+ //! future use or useful in backends
+ QString copyToPath;
+
+ QLONG copyFromRevision;
+ //! future use or useful in backends
+ QLONG copyToRevision;
+ };
+
+#if QT_VERSION < 0x040000
+ typedef QValueList<LogChangePathEntry> LogChangePathEntries;
+#else
+ typedef QList<LogChangePathEntry> LogChangePathEntries;
+#endif
+
+ class SVNQT_EXPORT LogEntry
+ {
+ public:
+ LogEntry ();
+
+ LogEntry (const svn_revnum_t revision,
+ const char * author,
+ const char * date,
+ const char * message);
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5)) || (SVN_VER_MAJOR > 1)
+ LogEntry(svn_log_entry_t*);
+#endif
+ void setDate(const char*date);
+
+ //! if -1 the entry is a fake entry and not real usable!
+ QLONG revision;
+ QLONG date;
+ QString author;
+ QString message;
+ LogChangePathEntries changedPaths;
+ QLIST<QLONG> m_MergedInRevisions;
+ };
+}
+
+SVNQT_EXPORT QDataStream &operator<<(QDataStream&s,const svn::LogEntry&r);
+SVNQT_EXPORT QDataStream &operator<<(QDataStream&s,const svn::LogChangePathEntry&r);
+
+SVNQT_EXPORT QDataStream &operator>>(QDataStream&s,svn::LogEntry&r);
+SVNQT_EXPORT QDataStream &operator>>(QDataStream&s,svn::LogChangePathEntry&r);
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/path.cpp b/src/svnqt/path.cpp
new file mode 100644
index 0000000..676c151
--- /dev/null
+++ b/src/svnqt/path.cpp
@@ -0,0 +1,290 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+
+// subversion api
+#include "svn_path.h"
+
+// apr api
+#include "apr_file_io.h"
+
+// svncpp
+#include "svnqt/path.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/url.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/revision.hpp"
+#include "svnqt/exception.hpp"
+
+#include <qurl.h>
+
+namespace svn
+{
+ Path::Path (const char * path)
+ {
+ init(QString::FROMUTF8(path));
+ }
+
+ Path::Path (const QString & path)
+ {
+ init (path);
+ }
+
+ Path::Path (const Path & path)
+ : m_path(path.m_path)
+ {
+ }
+
+ void
+ Path::init (const QString& path)
+ {
+ Pool pool;
+
+ if (path.isEmpty()) {
+ m_path = "";
+ } else {
+ const char * int_path = svn_path_internal_style (path.TOUTF8(), pool.pool () );
+ if (Url::isValid(path) ) {
+ if (!svn_path_is_uri_safe(int_path)) {
+ int_path = svn_path_uri_encode(int_path,pool);
+ }
+ }
+ m_path = QString::FROMUTF8(int_path);
+#if QT_VERSION < 0x040000
+ if (Url::isValid(path) && m_path.find("@")!=-1 ) {
+#else
+ if (Url::isValid(path) && m_path.indexOf("@")!=-1 ) {
+#endif
+ /// @todo make sure that "@" is never used as revision paramter
+ QUrl uri = m_path;
+ m_path = uri.path();
+ m_path.replace("@","%40");
+#if QT_VERSION < 0x040000
+ m_path = uri.protocol()+"://"+(uri.hasUser()?uri.user()+(uri.hasPassword()?":"+uri.password():"")+"@":"")
+ +uri.host()+m_path;
+#else
+ m_path = uri.scheme()+"://"+uri.authority()+m_path;
+#endif
+ if (m_path.endsWith("/")) {
+ int_path = svn_path_internal_style (path.TOUTF8(), pool.pool () );
+ m_path = QString::FROMUTF8(int_path);
+ }
+ }
+ }
+ }
+
+ bool Path::isUrl()const
+ {
+ return Url::isValid(m_path);
+ }
+
+ const QString &
+ Path::path () const
+ {
+ return m_path;
+ }
+
+ Path::operator const QString&()const
+ {
+ return m_path;
+ }
+
+ QString Path::prettyPath()const
+ {
+ if (!Url::isValid(m_path)) {
+ return m_path;
+ }
+ Pool pool;
+ const char * int_path = svn_path_uri_decode(m_path.TOUTF8(), pool.pool () );
+ QString _p = QString::FROMUTF8(int_path);
+ _p.replace("%40","@");
+ return _p;
+ }
+
+ const QByteArray
+ Path::cstr() const
+ {
+ return m_path.TOUTF8();
+ }
+
+ Path&
+ Path::operator=(const Path & path)
+ {
+ if (this == &path)
+ return *this;
+ m_path = path.path();
+ return *this;
+ }
+
+ bool
+ Path::isset () const
+ {
+ return m_path.length () > 0;
+ }
+
+ void
+ Path::addComponent (const QString& component)
+ {
+ Pool pool;
+
+ if (Url::isValid (m_path))
+ {
+ const char * newPath =
+ svn_path_url_add_component (m_path.TOUTF8(), component.TOUTF8(), pool);
+ m_path = QString::FROMUTF8(newPath);
+ }
+ else
+ {
+ svn_stringbuf_t * pathStringbuf =
+ svn_stringbuf_create (m_path.TOUTF8(), pool);
+
+ svn_path_add_component (pathStringbuf,
+ component.TOUTF8());
+
+ m_path = QString::FROMUTF8(pathStringbuf->data);
+ }
+ }
+
+
+ void
+ Path::addComponent (const char* component)
+ {
+ addComponent (QString::FROMUTF8(component));
+ }
+
+
+ void
+ Path::removeLast()
+ {
+ Pool pool;
+ if (m_path.length()<=1) {
+ m_path=QString::FROMUTF8("");
+ }
+ svn_stringbuf_t*pathStringbuf=
+ svn_stringbuf_create (m_path.TOUTF8(), pool);
+ svn_path_remove_component(pathStringbuf);
+ m_path = QString::FROMUTF8(pathStringbuf->data);
+ }
+
+ void
+ Path::split (QString & dirpath, QString & basename) const
+ {
+ Pool pool;
+
+ const char * cdirpath;
+ const char * cbasename;
+
+ svn_path_split (prettyPath().TOUTF8(), &cdirpath, &cbasename, pool);
+ dirpath = QString::FROMUTF8(cdirpath);
+ basename = QString::FROMUTF8(cbasename);
+ }
+
+
+ void
+ Path::split (QString & dir, QString & filename, QString & ext) const
+ {
+ QString basename;
+
+ // first split path into dir and filename+ext
+ split (dir, basename);
+
+ // next search for last .
+#if QT_VERSION < 0x040000
+ int pos = basename.findRev(QChar('.'));
+#else
+ int pos = basename.lastIndexOf(QChar('.'));
+#endif
+
+ if (pos == -1)
+ {
+ filename = basename;
+ ext = QString::fromLatin1("");
+ }
+ else
+ {
+ filename = basename.left(pos);
+ ext = basename.mid(pos+1);
+ }
+ }
+
+ Path
+ Path::getTempDir ()
+ {
+ const char * tempdir = 0;
+ Pool pool;
+
+ if (apr_temp_dir_get (&tempdir, pool) != APR_SUCCESS)
+ {
+ tempdir = 0;
+ }
+
+ return tempdir;
+ }
+
+ void
+ Path::parsePeg(const QString&pathorurl,Path&_path,svn::Revision&_peg)
+ {
+ const char *truepath = 0;
+ svn_opt_revision_t pegr;
+ svn_error_t *error = 0;
+ QByteArray _buf = pathorurl.TOUTF8();
+
+ Pool pool;
+ error = svn_opt_parse_path(&pegr, &truepath,_buf,pool);
+ if (error != 0) {
+ throw ClientException (error);
+ }
+ qDebug("Path: %s",truepath);
+ _peg = svn::Revision(&pegr);
+ _path=Path(truepath);
+ }
+
+ unsigned int
+ Path::length () const
+ {
+ return m_path.length ();
+ }
+
+
+ QString
+ Path::native () const
+ {
+ Pool pool;
+
+ return QString::FROMUTF8(svn_path_local_style (m_path.TOUTF8(), pool));
+ }
+
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/path.hpp b/src/svnqt/path.hpp
new file mode 100644
index 0000000..0d92fc2
--- /dev/null
+++ b/src/svnqt/path.hpp
@@ -0,0 +1,200 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_PATH_HPP_
+#define _SVNCPP_PATH_HPP_
+
+#include <qstring.h>
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/svnqttypes.hpp"
+
+namespace svn
+{
+ /**
+ * Encapsulation for Subversion Path handling
+ */
+ class SVNQT_EXPORT Path
+ {
+ private:
+ QString m_path;
+
+ /**
+ * initialize the class
+ *
+ * @param path Path string - when url this should NOT hold revision as @ parameter!!!!! (will filtered out)
+ */
+ void init (const QString& path);
+
+ public:
+ /**
+ * Constructor that takes a string as parameter.
+ * The string is converted to subversion internal
+ * representation. The string is copied.
+ *
+ * @param path Path string - when url this should NOT hold revision as @ parameter!!!!! (will filtered out)
+ */
+ Path (const QString & path = QString::null);
+
+ /**
+ * Constructor
+ *
+ * @see Path::Path (const QString &)
+ * @param path Path string - when url this should NOT hold revision as @ parameter!!!!! (will filtered out)
+ */
+ Path (const char * path);
+
+ /**
+ * Copy constructor
+ *
+ * @param path Path to be copied
+ */
+ Path (const Path & path);
+
+ /**
+ * Assignment operator
+ */
+ Path& operator=(const Path&);
+
+ /**
+ * @return Path string
+ */
+ const QString &
+ path () const;
+
+ /**
+ * @return Path string
+ */
+ operator const QString&()const;
+
+ /**
+ * @return Path as pretty url
+ */
+ QString prettyPath()const;
+
+ /**
+ * @return Path string as c string
+ */
+ const QByteArray cstr() const;
+
+ /**
+ * check whether a path is set. Right now
+ * this checks only if the string is non-
+ * empty.
+ *
+ * @return true if there is a path set
+ */
+ bool
+ isset() const;
+
+
+ /**
+ * adds a new URL component to the path
+ *
+ * @param component new component to add
+ */
+ void
+ addComponent (const char * component);
+
+
+ /**
+ * adds a new URL component to the path
+ *
+ * @param component new component to add
+ */
+ void
+ addComponent (const QString & component);
+
+ /** Reduce path to its parent folder.
+ * If the path length is 1 (eg., only "/") it will cleared so
+ * path length will get zero.
+ * @sa svn_path_remove_component
+ */
+ void
+ removeLast();
+
+
+ /**
+ * split path in its components
+ *
+ * @param dirpath directory/path component
+ * @param basename filename
+ */
+ void
+ split (QString & dirpath, QString & basename) const;
+
+
+ /**
+ * split path in its components including
+ * file extension
+ *
+ * @param dir directory component
+ * @param filename filename
+ * @param ext extension (including leading dot ".")
+ */
+ void
+ split (QString & dir, QString & filename, QString & ext) const;
+
+
+ /**
+ * returns the temporary directory
+ */
+ static Path
+ getTempDir ();
+
+ /** Parse a string for a peg revision
+ * @param pathorurl url to parse
+ * @param _path target to store the cleaned url
+ * @param _peg target where to store the peg url.
+ * @throw svn::ClientException on errors
+ */
+ static void
+ parsePeg(const QString&pathorurl,Path&_path,svn::Revision&_peg);
+
+
+ /** return the length of the path-string */
+ unsigned int
+ length () const;
+
+
+ /** returns the path with native separators */
+ QString
+ native () const;
+
+ /** returns if the path is a valid url, eg. points to a remote */
+ bool isUrl()const;
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/pool.cpp b/src/svnqt/pool.cpp
new file mode 100644
index 0000000..34ef947
--- /dev/null
+++ b/src/svnqt/pool.cpp
@@ -0,0 +1,94 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// svncpp
+#include "pool.hpp"
+
+
+namespace svn
+{
+ bool Pool::s_initialized = false;
+
+ apr_pool_t *
+ Pool::pool_create (apr_pool_t * parent)
+ {
+ if (!s_initialized) {
+ apr_pool_initialize();
+ s_initialized=true;
+ }
+ return svn_pool_create (parent);
+ }
+
+ Pool::Pool (apr_pool_t * parent)
+ : m_parent (parent), m_pool (pool_create (parent))
+ {
+ }
+
+ Pool::~Pool ()
+ {
+ if(m_pool)
+ {
+ svn_pool_destroy (m_pool);
+ }
+ }
+
+ apr_pool_t *
+ Pool::pool () const
+ {
+ return m_pool;
+ }
+
+ void
+ Pool::renew ()
+ {
+ if (m_pool)
+ {
+ svn_pool_destroy (m_pool);
+ }
+ m_pool = pool_create (m_parent);
+ }
+
+//TODO
+// apr_pool_t *
+// Pool::operator=(const Pool & pool)
+// {
+// return
+// if (this == &path)
+// return *this;
+// m_path = path.c_str();
+// return *this;
+// }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/pool.hpp b/src/svnqt/pool.hpp
new file mode 100644
index 0000000..accdd75
--- /dev/null
+++ b/src/svnqt/pool.hpp
@@ -0,0 +1,92 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_POOL_H_
+#define _SVNCPP_POOL_H_
+
+// subversion api
+#include "svn_pools.h"
+
+
+namespace svn
+{
+ /**
+ * Class for encapsulation of apr/subversion pools
+ */
+ class Pool
+ {
+ public:
+ /**
+ * creates a subpool new pool to an existing pool
+ *
+ * @param parent NULL -> global pool
+ */
+ Pool (apr_pool_t * parent = (apr_pool_t *)0);
+
+ virtual ~ Pool ();
+
+ /**
+ * @return apr handle to the pool
+ */
+ apr_pool_t *
+ pool () const;
+
+ /**
+ * operator to return apr handle to the pool
+ */
+ operator apr_pool_t * () const
+ {
+ return m_pool;
+ }
+
+ /**
+ * release pool and create a new one
+ */
+ void renew ();
+ private:
+ apr_pool_t * m_parent;
+ apr_pool_t * m_pool;
+
+ Pool& operator=(const Pool&);
+
+ Pool (const Pool &);
+
+ static bool s_initialized;
+ static apr_pool_t * pool_create (apr_pool_t * parent);
+ };
+}
+
+#endif
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/repository.cpp b/src/svnqt/repository.cpp
new file mode 100644
index 0000000..2a3dd0e
--- /dev/null
+++ b/src/svnqt/repository.cpp
@@ -0,0 +1,104 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "repository.hpp"
+#include "repositorydata.hpp"
+
+namespace svn {
+
+namespace repository {
+
+Repository::Repository(svn::repository::RepositoryListener*aListener)
+{
+ m_Data=new RepositoryData(aListener);
+}
+
+
+Repository::~Repository()
+{
+ delete m_Data;
+}
+
+
+/*!
+ \fn svn::Repository::Open(const QString&)
+ */
+void Repository::Open(const QString&name) throw (ClientException)
+{
+ svn_error_t * error = m_Data->Open(name);
+ if (error!=0) {
+ throw ClientException (error);
+ }
+}
+
+void Repository::CreateOpen(const QString&path, const QString&fstype, bool _bdbnosync, bool _bdbautologremove, bool _pre_1_4_compat, bool _pre_1_5_compat) throw (ClientException)
+{
+ svn_error_t * error = m_Data->CreateOpen(path,fstype,_bdbnosync,_bdbautologremove,_pre_1_4_compat,_pre_1_5_compat);
+ if (error!=0) {
+ throw ClientException (error);
+ }
+}
+
+
+/*!
+ \fn svn::Repository::dump(const QString&output,const svn::Revision&start,const svn::Revision&end, bool incremental, bool use_deltas)throw (ClientException)
+ */
+void Repository::dump(const QString&output,const svn::Revision&start,const svn::Revision&end, bool incremental, bool use_deltas)throw (ClientException)
+{
+ svn_error_t * error = m_Data->dump(output,start,end,incremental,use_deltas);
+ if (error!=0) {
+ throw ClientException (error);
+ }
+}
+
+void Repository::loaddump(const QString&dump,LOAD_UUID uuida, const QString&parentFolder, bool usePre, bool usePost)throw (ClientException)
+{
+ svn_repos_load_uuid uuid_action;
+ switch (uuida) {
+ case UUID_IGNORE_ACTION:
+ uuid_action=svn_repos_load_uuid_ignore;
+ break;
+ case UUID_FORCE_ACTION:
+ uuid_action=svn_repos_load_uuid_force ;
+ break;
+ case UUID_DEFAULT_ACTION:
+ default:
+ uuid_action=svn_repos_load_uuid_default;
+ break;
+ }
+ svn_error_t * error = m_Data->loaddump(dump,uuid_action,parentFolder,usePre,usePost);
+ if (error!=0) {
+ throw ClientException (error);
+ }
+}
+
+/*!
+ \fn svn::Repository::hotcopy(const QString&src,const QString&dest,bool cleanlogs)
+ */
+void Repository::hotcopy(const QString&src,const QString&dest,bool cleanlogs)throw (ClientException)
+{
+ svn_error_t * error = RepositoryData::hotcopy(src,dest,cleanlogs);
+ if (error!=0) {
+ throw ClientException (error);
+ }
+}
+
+} // namespace repository
+
+} // namespace svn
diff --git a/src/svnqt/repository.hpp b/src/svnqt/repository.hpp
new file mode 100644
index 0000000..e4ea5eb
--- /dev/null
+++ b/src/svnqt/repository.hpp
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef SVNREPOSITORY_H
+#define SVNREPOSITORY_H
+
+// Ignore MSVC 7, 2005 & 2008 compiler warning: C++ exception specification
+#if defined (_MSC_VER) && _MSC_VER > 1200 && _MSC_VER <= 1550
+#pragma warning (disable: 4290)
+#endif
+
+#include "svnqt/exception.hpp"
+#include "svnqt/revision.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qstring.h>
+
+namespace svn {
+
+namespace repository {
+
+class RepositoryData;
+class RepositoryListener;
+
+//! wrapper class for subversions administrative repository functions
+/*!
+ \author Rajko Albrecht <ral@alwins-world.de>
+*/
+class SVNQT_EXPORT Repository{
+public:
+ enum LOAD_UUID {
+ UUID_DEFAULT_ACTION = 0,
+ UUID_IGNORE_ACTION = 1,
+ UUID_FORCE_ACTION = 2
+ };
+ //! constructor
+ /*!
+ * \param aListener callback object, the object will NOT take the ownership.
+ */
+ Repository(svn::repository::RepositoryListener*aListener);
+ //! destructor
+ virtual ~Repository();
+
+ //! open a local repository path for maintainance
+ /*!
+ Assigns a repository with that object. If a path was opened before it will closed.
+ \param path Path to a local repository, must not be an url
+ \exception ClientException will be thrown in case of an error
+ */
+ void Open(const QString&path) throw (ClientException);
+ //! Creates and open a new repository
+ /*!
+ * Creates a new repository in path with type fstype. If create succeeded open and assigns with the object.
+ * If a repository was opened before it will closed.
+ * \param path the path where to create the new repository. Must not be an url.
+ * \param fstype type of repository ("fsfs" or "bdb"). If wrong is set fsfs is the default.
+ * \param _bdbnosync disable fsync at transaction commit [Berkeley DB]
+ * \param _bdbautologremove enable automatic log file removal [Berkeley DB]
+ * \param _pre_1_4_compat Create repository compatibel to version earlier than 1.4 (only used with subversion 1.4)
+ */
+ void CreateOpen(const QString&path, const QString&fstype, bool _bdbnosync = false,
+ bool _bdbautologremove = true, bool _pre_1_4_compat=false, bool _pre_1_5_compat=false) throw (ClientException);
+ //! dump content of repository to a file
+ /*!
+ The repository must opend before. Progress message go trough the assigned svn::repository::RepositoryListener object.
+ The revision parameter must be numbers, no constant values like svn::Revision::HEAD.
+ \param output where to output the content
+ \param start Begin on revision. If revision == -1 than start with first entry.
+ \param end End with revision. If revision == -1 than end with current head.
+ \param incremental dump incrementally
+ \param use_deltas use deltas in dump output
+ \exception ClientException will be thrown in case of an error
+ */
+ void dump(const QString&output,const svn::Revision&start,const svn::Revision&end, bool incremental, bool use_deltas)throw (ClientException);
+ //! load a dump into repository
+ /*!
+ The repository must opened before. Progress message go trough the assigned svn::repository::RepositoryListener object.
+ \param dump Dumpfile to load
+ \param uuida what to do with UUIDs
+ \param parentFolder put content of dumpstream within folder in repository, if empty put into root-folder.
+ \param usePre use pre-commit-hook
+ \param usePost use post-commit-hook
+ \exception ClientException will be thrown in case of an error
+ */
+ void loaddump(const QString&dump,LOAD_UUID uuida, const QString&parentFolder, bool usePre, bool usePost)throw (ClientException);
+ //! copy a repository to a new location
+ /*!
+ \param src the repository path to copy
+ \param dest where to copy
+ \param cleanlogs remove redundand log files from source
+ \exception ClientException will be thrown in case of an error
+ */
+ static void hotcopy(const QString&src,const QString&dest,bool cleanlogs)throw (ClientException);
+
+private:
+ RepositoryData*m_Data;
+};
+
+}
+
+}
+
+#endif
diff --git a/src/svnqt/repositorydata.cpp b/src/svnqt/repositorydata.cpp
new file mode 100644
index 0000000..2ab9c5d
--- /dev/null
+++ b/src/svnqt/repositorydata.cpp
@@ -0,0 +1,250 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "svnqt/repositorydata.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/exception.hpp"
+#include "svnqt/repositorylistener.hpp"
+#include "svnqt/svnfilestream.hpp"
+
+#include <svn_fs.h>
+#include <svn_path.h>
+#include <svn_config.h>
+
+namespace svn {
+
+namespace repository {
+
+class RepoOutStream:public stream::SvnStream
+{
+public:
+ RepoOutStream(RepositoryData*);
+ virtual ~RepoOutStream(){}
+
+ virtual bool isOk()const{return true;}
+ virtual long write(const char*data,const unsigned long max);
+
+protected:
+ RepositoryData*m_Back;
+};
+
+RepoOutStream::RepoOutStream(RepositoryData*aBack)
+ : SvnStream(false,true)
+{
+ m_Back = aBack;
+}
+
+long RepoOutStream::write(const char*data,const unsigned long max)
+{
+ if (m_Back) {
+ QString msg = QString::FROMUTF8(data,max);
+ m_Back->reposFsWarning(msg);
+ }
+ return max;
+}
+
+RepositoryData::RepositoryData(RepositoryListener*aListener)
+{
+ m_Repository = 0;
+ m_Listener = aListener;
+}
+
+
+RepositoryData::~RepositoryData()
+{
+}
+
+void RepositoryData::warning_func(void *baton, svn_error_t *err)
+{
+ RepositoryData*_r = (RepositoryData*)baton;
+
+ if (_r) {
+ QString msg = svn::Exception::error2msg(err);
+ svn_error_clear(err);
+ _r->reposFsWarning(msg);
+ }
+}
+
+void RepositoryData::reposFsWarning(const QString&msg)
+{
+ if (m_Listener) {
+ m_Listener->sendWarning(msg);
+ }
+}
+
+svn_error_t*RepositoryData::cancel_func(void*baton)
+{
+ RepositoryListener*m_L = (RepositoryListener*)baton;
+ if (m_L && m_L->isCanceld()) {
+ return svn_error_create (SVN_ERR_CANCELLED, 0, QString::FROMUTF8("Cancelled by user.").TOUTF8());
+ }
+ return SVN_NO_ERROR;
+}
+
+/*!
+ \fn svn::RepositoryData::close()
+ */
+void RepositoryData::Close()
+{
+ m_Pool.renew();
+ m_Repository = 0;
+}
+
+
+/*!
+ \fn svn::RepositoryData::Open(const QString&)
+ */
+svn_error_t * RepositoryData::Open(const QString&path)
+{
+ Close();
+ svn_error_t * error = svn_repos_open(&m_Repository,path.TOUTF8(),m_Pool);
+ if (error!=0L) {
+ m_Repository=0;
+ return error;
+ }
+ svn_fs_set_warning_func(svn_repos_fs(m_Repository), RepositoryData::warning_func, this);
+ return SVN_NO_ERROR;
+}
+
+
+/*!
+ \fn svn::RepositoryData::CreateOpen(const QString&path, const QString&fstype, bool _bdbnosync = false, bool _bdbautologremove = true, bool nosvn1diff=false)
+ */
+svn_error_t * RepositoryData::CreateOpen(const QString&path, const QString&fstype, bool _bdbnosync,
+ bool _bdbautologremove,
+ bool _pre_1_4_compat,
+ bool _pre_1_5_compat)
+{
+ Close();
+ const char* _type;
+#if QT_VERSION < 0x040000
+ if (fstype.lower()=="bdb") {
+#else
+ if (fstype.toLower()=="bdb") {
+#endif
+ _type="bdb";
+ } else {
+ _type="fsfs";
+ }
+ apr_hash_t *config;
+ apr_hash_t *fs_config = apr_hash_make(m_Pool);
+
+ apr_hash_set(fs_config, SVN_FS_CONFIG_BDB_TXN_NOSYNC,
+ APR_HASH_KEY_STRING,
+ (_bdbnosync ? "1" : "0"));
+ apr_hash_set(fs_config, SVN_FS_CONFIG_BDB_LOG_AUTOREMOVE,
+ APR_HASH_KEY_STRING,
+ (_bdbautologremove ? "1" : "0"));
+ apr_hash_set(fs_config, SVN_FS_CONFIG_FS_TYPE,
+ APR_HASH_KEY_STRING,
+ _type);
+
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 4) || SVN_VER_MAJOR>1)
+ if (_pre_1_4_compat) {
+ qDebug("Pre 14");
+ apr_hash_set(fs_config, SVN_FS_CONFIG_PRE_1_4_COMPATIBLE,
+ APR_HASH_KEY_STRING,"1");
+ }
+#else
+ Q_UNUSED(_pre_1_4_compat);
+#endif
+#if ((SVN_VER_MAJOR == 1) && (SVN_VER_MINOR >= 5) || SVN_VER_MAJOR>1)
+ if (_pre_1_5_compat) {
+ qDebug("Pre 15");
+ apr_hash_set(fs_config, SVN_FS_CONFIG_PRE_1_5_COMPATIBLE,
+ APR_HASH_KEY_STRING,"1");
+ }
+#else
+ Q_UNUSED(_pre_1_5_compat);
+#endif
+ /// @todo config as extra paramter? Meanwhile default config only
+ /// (see svn::ContextData)
+ SVN_ERR(svn_config_get_config(&config, 0, m_Pool));
+ const char*repository_path = apr_pstrdup (m_Pool,path.TOUTF8());
+
+ repository_path = svn_path_internal_style(repository_path, m_Pool);
+
+ if (svn_path_is_url(repository_path)) {
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ "'%s' is an URL when it should be a path",repository_path);
+ }
+ SVN_ERR(svn_repos_create(&m_Repository, repository_path,
+ NULL, NULL,config, fs_config,m_Pool));
+
+ svn_fs_set_warning_func(svn_repos_fs(m_Repository), RepositoryData::warning_func, this);
+
+ return SVN_NO_ERROR;
+}
+
+
+/*!
+ \fn svn::RepositoryData::dump(const QString&output,const svn::Revision&start,const svn::Revision&end, bool incremental, bool use_deltas)
+ */
+svn_error_t* RepositoryData::dump(const QString&output,const svn::Revision&start,const svn::Revision&end, bool incremental, bool use_deltas)
+{
+ if (!m_Repository) {
+ return svn_error_create(SVN_ERR_CANCELLED,0,"No repository selected.");
+ }
+ Pool pool;
+ svn::stream::SvnFileOStream out(output);
+ RepoOutStream backstream(this);
+ svn_revnum_t _s,_e;
+ _s = start.revnum();
+ _e = end.revnum();
+ SVN_ERR(svn_repos_dump_fs2(m_Repository,out,backstream,_s,_e,incremental,use_deltas,
+ RepositoryData::cancel_func,m_Listener,pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t* RepositoryData::loaddump(const QString&dump,svn_repos_load_uuid uuida, const QString&parentFolder, bool usePre, bool usePost)
+{
+ if (!m_Repository) {
+ return svn_error_create(SVN_ERR_CANCELLED,0,"No repository selected.");
+ }
+ svn::stream::SvnFileIStream infile(dump);
+ RepoOutStream backstream(this);
+ Pool pool;
+ const char*src_path = apr_pstrdup (pool,dump.TOUTF8());
+ const char*dest_path;
+ if (parentFolder.isEmpty()) {
+ dest_path=0;
+ } else {
+ dest_path=apr_pstrdup (pool,parentFolder.TOUTF8());
+ }
+
+ src_path = svn_path_internal_style(src_path, pool);
+ SVN_ERR(svn_repos_load_fs2(m_Repository,infile,backstream,uuida,dest_path,usePre?1:0,usePost?1:0,RepositoryData::cancel_func,m_Listener,pool));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t* RepositoryData::hotcopy(const QString&src,const QString&dest,bool cleanlogs)
+{
+ Pool pool;
+ const char*src_path = apr_pstrdup (pool,src.TOUTF8());
+ const char*dest_path = apr_pstrdup (pool,dest.TOUTF8());
+ src_path = svn_path_internal_style(src_path, pool);
+ dest_path = svn_path_internal_style(dest_path, pool);
+ SVN_ERR(svn_repos_hotcopy(src_path,dest_path,cleanlogs?1:0,pool));
+ return SVN_NO_ERROR;
+}
+
+}
+
+}
diff --git a/src/svnqt/repositorydata.hpp b/src/svnqt/repositorydata.hpp
new file mode 100644
index 0000000..9884b70
--- /dev/null
+++ b/src/svnqt/repositorydata.hpp
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef SVNREPOSITORYDATA_H
+#define SVNREPOSITORYDATA_H
+
+#include "svnqt/pool.hpp"
+#include "svnqt/revision.hpp"
+#include "svnqt/apr.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qstring.h>
+
+#include <svn_repos.h>
+#include <svn_error.h>
+
+namespace svn {
+
+namespace repository {
+
+class Repository;
+class RepositoryListener;
+/**
+ @author Rajko Albrecht <ral@alwins-world.de>
+*/
+class SVNQT_NOEXPORT RepositoryData{
+ friend class Repository;
+
+public:
+ RepositoryData(RepositoryListener*);
+
+ virtual ~RepositoryData();
+ void Close();
+ svn_error_t * Open(const QString&);
+ svn_error_t * CreateOpen(const QString&path, const QString&fstype, bool _bdbnosync = false,
+ bool _bdbautologremove = true, bool _pre_1_4_compat=false, bool _pre_1_5_compat=false);
+
+ void reposFsWarning(const QString&msg);
+ svn_error_t* dump(const QString&output,const svn::Revision&start,const svn::Revision&end, bool incremental, bool use_deltas);
+ svn_error_t* loaddump(const QString&dump,svn_repos_load_uuid uuida, const QString&parentFolder, bool usePre, bool usePost);
+ static svn_error_t* hotcopy(const QString&src,const QString&dest,bool cleanlogs);
+
+protected:
+ Pool m_Pool;
+ svn_repos_t*m_Repository;
+ RepositoryListener*m_Listener;
+
+private:
+ static void warning_func(void *baton, svn_error_t *err);
+ static svn_error_t*cancel_func(void*baton);
+};
+
+}
+
+}
+
+#endif
diff --git a/src/svnqt/repositorylistener.cpp b/src/svnqt/repositorylistener.cpp
new file mode 100644
index 0000000..9c809a8
--- /dev/null
+++ b/src/svnqt/repositorylistener.cpp
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "repositorylistener.hpp"
+
+namespace svn {
+
+namespace repository {
+
+RepositoryListener::RepositoryListener()
+{
+}
+
+
+RepositoryListener::~RepositoryListener()
+{
+}
+
+}
+
+}
diff --git a/src/svnqt/repositorylistener.hpp b/src/svnqt/repositorylistener.hpp
new file mode 100644
index 0000000..15d650d
--- /dev/null
+++ b/src/svnqt/repositorylistener.hpp
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef REPOSITORYLISTENER_HPP
+#define REPOSITORYLISTENER_HPP
+
+/**
+ @author Rajko Albrecht <ral@alwins-world.de>
+*/
+
+#include "svnqt/svnqt_defines.hpp"
+#include <qstring.h>
+
+namespace svn {
+
+namespace repository {
+
+//! class for callbacks on repository operations
+class SVNQT_EXPORT RepositoryListener{
+
+public:
+ //! constructor
+ RepositoryListener();
+ //! destructor
+ virtual ~RepositoryListener();
+
+ //! sends a warning or informative message
+ virtual void sendWarning(const QString&)=0;
+ //! sends an error message
+ virtual void sendError(const QString&)=0;
+ //! check if running operation should cancelled
+ virtual bool isCanceld() =0;
+
+};
+
+}
+
+}
+
+#endif
diff --git a/src/svnqt/revision.cpp b/src/svnqt/revision.cpp
new file mode 100644
index 0000000..a89fae1
--- /dev/null
+++ b/src/svnqt/revision.cpp
@@ -0,0 +1,299 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+
+// svncpp
+#include "revision.hpp"
+#include "pool.hpp"
+
+// qt
+#include "qdatetime.h"
+
+namespace svn
+{
+ const svn_opt_revision_kind Revision::START = svn_opt_revision_number;
+ const svn_opt_revision_kind Revision::BASE = svn_opt_revision_base;
+ const svn_opt_revision_kind Revision::HEAD = svn_opt_revision_head;
+ const svn_opt_revision_kind Revision::WORKING = svn_opt_revision_working;
+ const svn_opt_revision_kind Revision::UNDEFINED = svn_opt_revision_unspecified;
+ const svn_opt_revision_kind Revision::PREV = svn_opt_revision_previous;
+
+ const svn_opt_revision_kind Revision::DATE = svn_opt_revision_date;
+ const svn_opt_revision_kind Revision::NUMBER = Revision::START;
+
+
+ Revision::Revision (const svn_opt_revision_t * revision)
+ {
+ init (revision);
+ }
+
+ Revision::Revision (const svn_revnum_t revnum)
+ {
+ if (revnum<0) {
+ m_revision.kind = svn_opt_revision_unspecified;
+ m_revision.value.number = 0;
+ } else {
+ m_revision.kind = svn_opt_revision_number;
+ m_revision.value.number = revnum;
+ }
+ }
+
+ Revision::Revision (const svn_opt_revision_kind kind)
+ {
+ m_revision.kind = kind;
+ m_revision.value.number = 0;
+ }
+
+ Revision::Revision (const int revnum, const QString&revstring)
+ {
+ m_revision.kind = svn_opt_revision_unspecified;
+
+ if (revnum > -1) {
+ m_revision.kind = svn_opt_revision_number;
+ m_revision.value.number = revnum;
+ } else {
+ assign(revstring);
+ }
+ }
+
+ Revision::Revision (const QString&revstring)
+ {
+ assign(revstring);
+ }
+
+ void
+ Revision::assign(const QString&revstring)
+ {
+ m_revision.kind = svn_opt_revision_unspecified;
+ if (revstring.isEmpty()) {
+ return;
+ }
+ if (revstring=="WORKING") {
+ m_revision.kind = WORKING;
+ } else if (revstring=="BASE") {
+ m_revision.kind = BASE;
+ } else if (revstring=="START"){
+ m_revision.kind = Revision::START;
+ m_revision.value.number = 0;
+ } else if (revstring=="PREV"){
+ m_revision.kind = Revision::PREV;
+ } else if (!revstring.isNull()) {
+ Pool pool;
+ svn_opt_revision_t endrev;
+ svn_opt_parse_revision(&m_revision,&endrev,revstring.TOUTF8(),pool);
+ }
+ }
+
+ void
+ Revision::assign(const QDateTime&dateTime)
+ {
+ m_revision.kind = svn_opt_revision_date;
+ DateTime dt(dateTime);
+ m_revision.value.date = dt.GetAPRTimeT();
+ }
+
+ Revision& Revision::operator=(const QString&what)
+ {
+ assign(what);
+ return *this;
+ }
+
+ Revision::Revision (const DateTime dateTime)
+ {
+ m_revision.kind = svn_opt_revision_date;
+ m_revision.value.date = dateTime.GetAPRTimeT();
+ }
+
+ Revision::Revision (const QDateTime&dateTime)
+ {
+ assign(dateTime);
+ }
+
+ Revision::Revision (const Revision & revision)
+ {
+ init (revision.revision ());
+ }
+
+ void
+ Revision::init (const svn_opt_revision_t * revision)
+ {
+ if( !revision )
+ {
+ m_revision.kind = svn_opt_revision_unspecified;
+ }
+ else
+ {
+ m_revision.kind = revision->kind;
+
+ // m_revision.value is a union so we are not
+ // allowed to set number if we want to use date
+ // and vice versa
+
+ switch( revision->kind )
+ {
+ case svn_opt_revision_number:
+ m_revision.value.number = revision->value.number;
+ break;
+
+ case svn_opt_revision_date:
+ m_revision.value.date = revision->value.date;
+ break;
+
+ default:
+ m_revision.value.number = 0;
+ }
+ }
+ }
+
+ Revision::operator QString ()const
+ {
+ return toString();
+ }
+
+ QString Revision::toString()const
+ {
+ QString value;
+ QDateTime result;
+ switch (m_revision.kind) {
+ case svn_opt_revision_number:
+ value.sprintf("%li",m_revision.value.number);
+ break;
+ case svn_opt_revision_date:
+ value = DateTime(m_revision.value.date).toString("{yyyy-MM-dd}");
+ break;
+ case svn_opt_revision_base:
+ value = "BASE";
+ break;
+ case svn_opt_revision_head:
+ value = "HEAD";
+ break;
+ case svn_opt_revision_working:
+ value = "WORKING";
+ break;
+ case svn_opt_revision_previous:
+ value="PREVIOUS";
+ break;
+ case svn_opt_revision_unspecified:
+ default:
+ value="-1";
+ break;
+ }
+ return value;
+ }
+
+ const svn_opt_revision_t *
+ Revision::revision () const
+ {
+ return &m_revision;
+ }
+
+ svn_revnum_t
+ Revision::revnum () const
+ {
+ if (m_revision.kind==svn_opt_revision_number) {
+ return m_revision.value.number;
+ }
+ return SVN_INVALID_REVNUM;
+ }
+
+ apr_time_t
+ Revision::date () const
+ {
+ return m_revision.value.date;
+ }
+
+ svn_opt_revision_kind
+ Revision::kind () const
+ {
+ return m_revision.kind;
+ }
+
+ bool Revision::operator==(const Revision&r)const
+ {
+ if (r.kind()!=kind()) {
+ return false;
+ }
+ if (m_revision.kind == svn_opt_revision_number) {
+ return revnum()==r.revnum();
+ } else if (m_revision.kind == svn_opt_revision_date) {
+ return date()==r.date();
+ }
+ return true;
+ }
+
+ bool Revision::operator==(int value)const
+ {
+ if (m_revision.kind!=svn_opt_revision_number || value!=revnum()) {
+ return false;
+ }
+ return true;
+ }
+
+ bool Revision::operator!=(const svn_opt_revision_kind t)const
+ {
+ return kind()!=t;
+ }
+ bool Revision::operator==(const svn_opt_revision_kind t)const
+ {
+ return kind()==t;
+ }
+
+ bool Revision::operator!()const
+ {
+ return kind()==UNDEFINED;
+ }
+
+ bool Revision::operator!()
+ {
+ return kind()==UNDEFINED;
+ }
+
+ Revision::operator bool()const
+ {
+ return kind()!=UNDEFINED;
+ }
+
+ Revision::operator bool()
+ {
+ return kind()!=UNDEFINED;
+ }
+
+ bool Revision::isRemote()const
+ {
+ return kind()!=UNDEFINED && kind()!=BASE && kind()!=WORKING;
+ }
+
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/revision.hpp b/src/svnqt/revision.hpp
new file mode 100644
index 0000000..371b1a1
--- /dev/null
+++ b/src/svnqt/revision.hpp
@@ -0,0 +1,222 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_REVISION_HPP_
+#define _SVNCPP_REVISION_HPP_
+
+// svncpp
+#include <svnqt/datetime.hpp>
+#include <svnqt/svnqt_defines.hpp>
+
+// qt
+#include <qglobal.h>
+#if QT_VERSION < 0x040000
+ #include <qstring.h>
+ #include <qtextstream.h>
+#else
+ #include <QtCore>
+#endif
+
+// subversion api
+#include "svn_types.h"
+#include "svn_opt.h"
+
+namespace svn
+{
+ /**
+ * Class that encapsulates svn_opt_revnum_t.
+ *
+ * @see svn_opt_revnum_t
+ */
+ class SVNQT_EXPORT Revision
+ {
+ private:
+ svn_opt_revision_t m_revision;
+
+ void
+ init (const svn_opt_revision_t * revision);
+
+ void
+ assign(const QString&);
+
+ void
+ assign(const QDateTime&);
+
+ public:
+ static const svn_opt_revision_kind START;
+ static const svn_opt_revision_kind BASE;
+ static const svn_opt_revision_kind HEAD;
+ static const svn_opt_revision_kind WORKING;
+ static const svn_opt_revision_kind UNDEFINED;
+ static const svn_opt_revision_kind PREV;
+
+ static const svn_opt_revision_kind DATE;
+ static const svn_opt_revision_kind NUMBER;
+
+ /**
+ * Constructor
+ *
+ * @param revision revision information
+ */
+ Revision (const svn_opt_revision_t * revision);
+
+ /**
+ * Constructor
+ *
+ * @param revnum revision number
+ */
+ Revision (const svn_revnum_t revnum);
+
+ /**
+ * Constructor
+ * @param revnum a revision number
+ * @param revstring a revision string
+ *
+ * The revision string MUST uppercase, it may some of "HEAD", "BASE", "WORKING", "COMMITED", "PREV",
+ * or a date in form {YYYY-MM-DD}.
+ */
+ Revision (const int revnum, const QString&revstring);
+
+ /**
+ * Constructor
+ * @param revstring a revision string
+ *
+ * The revision string MUST uppercase, it may some of "HEAD", "BASE", "WORKING", "COMMITED", "PREV",
+ * or a date in form {YYYY-MM-DD}.
+ */
+ Revision (const QString&revstring);
+
+ /**
+ * Constructor
+ *
+ * @param kind
+ */
+ Revision (const svn_opt_revision_kind kind = svn_opt_revision_unspecified);
+
+ /**
+ * Constructor
+ *
+ * @param dateTime DateTime wrapper for apr_time_t
+ * @todo change it to referenced parameter (requires interface upgrade of lib)
+ */
+ Revision (const DateTime dateTime);
+ /**
+ * Constructor
+ *
+ * @param dateTime QDateTime type
+ */
+ Revision (const QDateTime&dateTime);
+
+ /**
+ * Copy constructor
+ *
+ * @param revision Source
+ */
+ Revision (const Revision & revision);
+
+ /**
+ * @return revision information
+ */
+ const svn_opt_revision_t *
+ revision () const;
+
+ /**
+ * @see revision (). Same function
+ * but with operator overloading
+ */
+ operator svn_opt_revision_t * ()
+ {
+ return &m_revision;
+ }
+
+ /**
+ * @see revision (). Same function
+ * but with operator overloading
+ */
+ operator const svn_opt_revision_t*()const
+ {
+ return &m_revision;
+ }
+
+ /**
+ * @return revision numver
+ */
+ svn_revnum_t
+ revnum () const;
+
+ /**
+ * @return revision kind
+ */
+ svn_opt_revision_kind
+ kind () const;
+
+ operator QString ()const;
+ QString toString()const;
+
+ bool isRemote()const;
+
+ /**
+ * @return date
+ */
+ apr_time_t
+ date () const;
+
+ bool operator==(const Revision&)const;
+ bool operator!=(const svn_opt_revision_kind)const;
+ bool operator==(const svn_opt_revision_kind)const;
+ bool operator==(int)const;
+
+ bool operator!()const;
+ bool operator!();
+ operator bool()const;
+ operator bool();
+
+ /**
+ * assignment operator
+ * @param what a simple revision string (not s:e but s)
+ * @return object itself
+ */
+ Revision& operator=(const QString&what);
+
+ };
+}
+
+inline QTextStream& operator<<(QTextStream&s,svn::Revision&r)
+{
+ s << r.toString();
+ return s;
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/shared_pointer.hpp b/src/svnqt/shared_pointer.hpp
new file mode 100644
index 0000000..cd1587e
--- /dev/null
+++ b/src/svnqt/shared_pointer.hpp
@@ -0,0 +1,193 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef SVNQT_SHARED_POINTER_HPP
+#define SVNQT_SHARED_POINTER_HPP
+
+#include "svnqt/smart_pointer.hpp"
+
+/*!
+ * \file shared_pointer.hpp
+ * \brief shared pointer adapter
+ * \sa smart_pointer.hpp
+ */
+
+namespace svn
+{
+
+template<class T> class SharedPointer;
+
+/*!
+ * Data container for svn::SharedPointer
+ */
+template<class T> class SharedPointerData:public ref_count
+{
+ friend class SharedPointer<T>;
+protected:
+ //! The protected pointer
+ T*data;
+public:
+ //! Constructor
+ /*!
+ * Take ownership of pointer dt
+ * \param dt the data to wrap
+ **/
+ SharedPointerData(T*dt){
+ data = dt;
+ }
+ //! Destructor
+ /*!
+ * Release content data
+ */
+ ~SharedPointerData() {
+ delete data;
+ }
+};
+
+//! Shared pointer adapater
+/*!
+ * Implements a thread safe reference counter around any pointer.
+ * This class takes ownership of data, eg., last reference will delete
+ * the data it inspects.
+ */
+template<class T> class SharedPointer
+{
+ typedef SharedPointerData<T> Data;
+ Data*data;
+
+ //! count down reference of data and release if it was the last share
+ void unref(){
+ if (data) {
+ data->Decr();
+ if (!data->Shared()) {
+ delete data;
+ }
+ data = 0;
+ }
+ }
+public:
+ //! empty constructor
+ SharedPointer():data(0){}
+ //! copy constructor
+ /*!
+ * \param p Data to increase reference for
+ */
+ SharedPointer(const SharedPointer<T>& p)
+ {
+ if ( (data = p.data) ) data->Incr();
+ }
+ //! assignment constructor
+ /*!
+ * Take ownership of data pointer t
+ * \param t data pointer to store inside
+ */
+ SharedPointer(T*t)
+ {
+ data = new Data(t);data->Incr();
+ }
+ //! destructor
+ /*!
+ * decrease reference, if reference == 0 release data
+ */
+ ~SharedPointer()
+ {
+ unref();
+ }
+
+ //! assignment operator
+ /*!
+ * \param p Data to increase reference for
+ */
+ SharedPointer<T> &operator=(const SharedPointer<T>&p)
+ {
+ // we always have a reference to the data
+ if (data==p.data) return *this;
+ unref();
+ if ((data=p.data)) data->Incr();
+ return *this;
+ }
+ //! assignment operator
+ /*!
+ * \param p Data to increase reference for
+ */
+ SharedPointer<T> &operator=(T*p)
+ {
+ if (data && data->data==p) {
+ return *this;
+ }
+ unref();
+ data = new Data(p);
+ data->Incr();
+ return *this;
+ }
+
+ //! access operator
+ /*!
+ * Use this operator with care!
+ * \return pointer to wrapped data
+ */
+ operator T*()const {return data->data;}
+ //! access operator
+ /*!
+ * \return reference to wrapped data
+ */
+ T& operator*() {return *data->data;}
+ //! access operator
+ /*!
+ * \return const reference to wrapped data
+ */
+ const T& operator*()const{return *data->data;}
+ //! access operator
+ /*!
+ * \return pointer to wrapped data
+ */
+ T*operator->() {return data->data;}
+ //! access operator
+ /*!
+ * \return const pointer to wrapped data
+ */
+ const T*operator->()const{return data->data;}
+
+ //! Bool operator
+ /*!
+ * \return true if content set and not a null-pointer, otherwise false
+ */
+ operator bool () const { return (data != 0 && data->data != 0); }
+ //! Bool operator
+ /*!
+ * \return true if content set and not a null-pointer, otherwise false
+ */
+ operator bool () { return ( data != 0 && data->data != 0 );}
+
+ //! Negation operator
+ /*!
+ * \return true if content not set or a null-pointer, otherwise false
+ */
+ bool operator! () const { return (data == 0 || data->data == 0); }
+ //! Negation operator
+ /*!
+ * \return true if content not set or a null-pointer, otherwise false
+ */
+ bool operator! () { return (data == 0 || data->data == 0); }
+};
+
+}
+
+#endif
diff --git a/src/svnqt/smart_pointer.hpp b/src/svnqt/smart_pointer.hpp
new file mode 100644
index 0000000..2790df5
--- /dev/null
+++ b/src/svnqt/smart_pointer.hpp
@@ -0,0 +1,146 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef _smart_pointer_hpp
+#define _smart_pointer_hpp
+
+#if defined QT_THREAD_SUPPORT
+#include "qmutex.h"
+#endif
+
+#include "svnqt/svnqt_defines.hpp"
+
+/*!
+ * \file smart_pointer.h
+ * \brief smart pointer and reference counter
+ * \author Rajko Albrecht
+ *
+ */
+
+namespace svn
+{
+
+//! simple reference counter class
+class ref_count {
+protected:
+ //! reference count member
+ long m_RefCount;
+#ifdef QT_THREAD_SUPPORT
+ QMutex m_RefcountMutex;
+#endif
+public:
+ //! first reference must be added after "new" via Pointer()
+ ref_count() : m_RefCount(0)
+#ifdef QT_THREAD_SUPPORT
+ ,m_RefcountMutex()
+#endif
+ {}
+ virtual ~ref_count() {}
+ //! add a reference
+ void Incr() {
+#ifdef QT_THREAD_SUPPORT
+ QMutexLocker a(&m_RefcountMutex);
+#endif
+ ++m_RefCount;
+ }
+ //! delete a reference
+ bool Decr() {
+#ifdef QT_THREAD_SUPPORT
+ QMutexLocker a(&m_RefcountMutex);
+#endif
+ --m_RefCount;
+ return Shared();
+ }
+ //! is it referenced
+ bool Shared() { return (m_RefCount > 0); }
+};
+
+//! reference counting wrapper class
+template<class T> class smart_pointer {
+ //! pointer to object
+ /*!
+ * this object must contain Incr(), Decr() and Shared()
+ * methode as public members. The best way is, that it will be a child
+ * class of RefCount
+ */
+ T *ptr;
+public:
+ //! standart constructor
+ smart_pointer() { ptr = 0; }
+ //! standart destructor
+ /*!
+ * release the reference, if it were the last reference, destroys
+ * ptr
+ */
+ ~smart_pointer()
+ {
+ if (ptr && !ptr->Decr()) {
+ delete ptr;
+ }
+ }
+ //! construction
+ smart_pointer(T* t) { if ( (ptr = t) ) ptr->Incr(); }
+ //! Pointer copy
+ smart_pointer(const smart_pointer<T>& p)
+ { if ( (ptr = p.ptr) ) ptr->Incr(); }
+ //! pointer copy by assignment
+ smart_pointer<T>& operator= (const smart_pointer<T>& p)
+ {
+ // already same: nothing to do
+ if (ptr == p.ptr) return *this;
+ // decouple reference
+ if ( ptr && !ptr->Decr()) delete ptr;
+ // establish new reference
+ if ( (ptr = p.ptr) ) ptr->Incr();
+ return *this;
+ }
+ smart_pointer<T>& operator= (T*p)
+ {
+ if (ptr==p)return *this;
+ if (ptr && !ptr->Decr()) delete ptr;
+ if ( (ptr=p) ) ptr->Incr();
+ return *this;
+ }
+
+ //! cast to conventional pointer
+ operator T* () const { return ptr; }
+
+ //! deref: fails for 0 pointer
+ T& operator* () {return *ptr; }
+ //! deref: fails for 0 pointer
+ const T& operator* ()const {return *ptr; }
+
+ //! deref with method call
+ T* operator-> () {return ptr; }
+ //! deref with const method call
+ const T* operator-> ()const {return ptr; }
+
+ //! supports "if (pointer)"
+ operator bool () const { return (ptr != 0); }
+ //! "if (pointer)" as non const
+ operator bool () { return ptr != 0;}
+
+ //! support if (!pointer)"
+ bool operator! () const { return (ptr == 0); }
+ //! support if (!pointer)" as non const
+ bool operator! () { return (ptr == 0); }
+};
+
+} // namespace svn
+#endif
diff --git a/src/svnqt/status.cpp b/src/svnqt/status.cpp
new file mode 100644
index 0000000..15a4af0
--- /dev/null
+++ b/src/svnqt/status.cpp
@@ -0,0 +1,319 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// svncpp
+#include "status.hpp"
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/path.hpp"
+#include "svnqt/url.hpp"
+
+#include "svn_path.h"
+
+namespace svn
+{
+ class SVNQT_NOEXPORT Status_private
+ {
+ public:
+ Status_private();
+ virtual ~Status_private();
+ /**
+ * Initialize structures
+ *
+ * @param path
+ * @param status if NULL isVersioned will be false
+ */
+ void
+ init (const QString&path, const svn_wc_status2_t * status);
+ void
+ init (const QString&path,const Status_private&src);
+ void
+ init(const QString&url,const DirEntryPtr&src);
+ void
+ init(const QString&url,const InfoEntry&src);
+
+ void setPath(const QString&);
+
+ QString m_Path;
+ bool m_isVersioned;
+ bool m_hasReal;
+ LockEntry m_Lock;
+ Entry m_entry;
+
+ svn_wc_status_kind _text_status,_prop_status,_repos_text_status,_repos_prop_status;
+ bool _copied,_switched;
+ };
+
+ Status_private::Status_private()
+ :m_Path(),m_isVersioned(false),m_hasReal(false)
+ {
+ }
+
+ Status_private::~ Status_private()
+ {
+ }
+
+ void Status_private::setPath(const QString&aPath)
+ {
+ Pool pool;
+ if (!Url::isValid(aPath)) {
+ m_Path = aPath;
+ } else {
+ const char * int_path = svn_path_uri_decode(aPath.TOUTF8(), pool.pool () );
+ m_Path = QString::FROMUTF8(int_path);
+ }
+ }
+
+ void Status_private::init (const QString&path, const svn_wc_status2_t * status)
+ {
+ setPath(path);
+ if (!status)
+ {
+ m_isVersioned = false;
+ m_hasReal = false;
+ m_entry=Entry();
+ m_Lock = LockEntry();
+ }
+ else
+ {
+ m_isVersioned = status->text_status > svn_wc_status_unversioned||status->repos_text_status>svn_wc_status_unversioned;
+ m_hasReal = m_isVersioned &&
+ status->text_status!=svn_wc_status_ignored;
+ // now duplicate the contents
+ if (status->entry)
+ {
+ m_entry = Entry(status->entry);
+ } else {
+ m_entry=Entry();
+ }
+ _text_status = status->text_status;
+ _prop_status = status->prop_status;
+ _copied = status->copied!=0;
+ _switched = status->switched!=0;
+ _repos_text_status = status->repos_text_status;
+ _repos_prop_status = status->repos_prop_status;
+ if (status->repos_lock) {
+ m_Lock.init(status->repos_lock->creation_date,
+ status->repos_lock->expiration_date,
+ status->repos_lock->owner,
+ status->repos_lock->comment,
+ status->repos_lock->token);
+ } else {
+ m_Lock=LockEntry();
+ }
+ }
+ }
+
+ void
+ Status_private::init (const QString&path,const Status_private&src)
+ {
+ setPath(path);
+ m_Lock=src.m_Lock;
+ m_entry=src.m_entry;
+ m_isVersioned=src.m_isVersioned;
+ m_hasReal=src.m_hasReal;
+ _text_status=src._text_status;
+ _prop_status=src._prop_status;
+ _repos_text_status=src._repos_text_status;
+ _repos_prop_status=src._repos_prop_status;
+ _copied=src._copied;
+ _switched=src._switched;
+ }
+
+ void Status_private::init(const QString&url,const DirEntryPtr&src)
+ {
+ m_entry=Entry(url,src);
+ setPath(url);
+ _text_status = svn_wc_status_normal;
+ _prop_status = svn_wc_status_normal;
+ if (src) {
+ m_Lock=src->lockEntry();
+ m_isVersioned=true;
+ m_hasReal=true;
+ }
+ _switched = false;
+ _repos_text_status = svn_wc_status_normal;
+ _repos_prop_status = svn_wc_status_normal;
+ }
+
+ void Status_private::init(const QString&url,const InfoEntry&src)
+ {
+ m_entry=Entry(url,src);
+ setPath(url);
+ m_Lock=src.lockEntry();
+ _text_status = svn_wc_status_normal;
+ _prop_status = svn_wc_status_normal;
+ _repos_text_status = svn_wc_status_normal;
+ _repos_prop_status = svn_wc_status_normal;
+ m_isVersioned=true;
+ m_hasReal=true;
+ }
+
+ Status::Status (const Status & src)
+ : m_Data(new Status_private())
+ {
+ if( &src != this )
+ {
+ if (src.m_Data) {
+ m_Data->init (src.m_Data->m_Path, *(src.m_Data));
+ } else {
+ m_Data->init(src.m_Data->m_Path,0);
+ }
+ }
+ }
+
+ Status::Status (const QString&path, svn_wc_status2_t * status)
+ : m_Data(new Status_private())
+ {
+ m_Data->init(path, status);
+ }
+
+ Status::Status (const char*path, svn_wc_status2_t * status)
+ : m_Data(new Status_private())
+ {
+ m_Data->init(QString::FROMUTF8(path),status);
+ }
+
+ Status::Status(const QString&url,const DirEntryPtr&src)
+ : m_Data(new Status_private())
+ {
+ m_Data->init(url,src);
+ }
+
+ Status::Status(const QString&url,const InfoEntry&src)
+ : m_Data(new Status_private())
+ {
+ m_Data->init(url,src);
+ }
+
+ Status::~Status ()
+ {
+ delete m_Data;
+ }
+
+ Status &
+ Status::operator=(const Status & status)
+ {
+ if (this == &status)
+ return *this;
+ if (status.m_Data) {
+ m_Data->init (status.m_Data->m_Path, *(status.m_Data));
+ } else {
+ m_Data->init(status.m_Data->m_Path,0);
+ }
+ return *this;
+ }
+
+ const LockEntry&
+ Status::lockEntry () const
+ {
+ return m_Data->m_Lock;
+ }
+ svn_wc_status_kind
+ Status::reposPropStatus () const
+ {
+ return m_Data->_repos_prop_status;
+ }
+ svn_wc_status_kind
+ Status::reposTextStatus () const
+ {
+ return m_Data->_repos_text_status;
+ }
+ bool
+ Status::isSwitched () const
+ {
+ return m_Data->_switched != 0;
+ }
+ bool
+ Status::isCopied () const
+ {
+ return m_Data->_copied;
+ }
+
+ bool
+ Status::isLocked () const
+ {
+ return m_Data->m_Lock.Locked();
+ }
+
+ bool
+ Status::isModified()const
+ {
+ return textStatus()==svn_wc_status_modified||propStatus()==svn_wc_status_modified
+ ||textStatus ()==svn_wc_status_replaced;
+ }
+
+ bool
+ Status::isRealVersioned()const
+ {
+ return m_Data->m_hasReal;
+ }
+
+ bool
+ Status::isVersioned () const
+ {
+ return m_Data->m_isVersioned;
+ }
+
+ svn_wc_status_kind
+ Status::propStatus () const
+ {
+ return m_Data->_prop_status;
+ }
+
+ svn_wc_status_kind
+ Status::textStatus () const
+ {
+ return m_Data->_text_status;
+ }
+
+ const Entry&
+ Status::entry () const
+ {
+ return m_Data->m_entry;
+ }
+
+ const QString&
+ Status::path () const
+ {
+ return m_Data->m_Path;
+ }
+
+ bool
+ Status::validReposStatus()const
+ {
+ return reposTextStatus()!=svn_wc_status_none||reposPropStatus()!=svn_wc_status_none;
+ }
+
+ bool
+ Status::validLocalStatus()const
+ {
+ return textStatus()!=svn_wc_status_none||propStatus()!=svn_wc_status_none;
+ }
+}
diff --git a/src/svnqt/status.hpp b/src/svnqt/status.hpp
new file mode 100644
index 0000000..ec0f436
--- /dev/null
+++ b/src/svnqt/status.hpp
@@ -0,0 +1,187 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#ifndef _SVNCPP_STATUS_HPP_
+#define _SVNCPP_STATUS_HPP_
+
+// subversion api
+#include "svn_wc.h"
+
+// svncpp
+#include "svnqt/svnqttypes.hpp"
+#include "svnqt/entry.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/lock_entry.hpp"
+#include "svnqt/dirent.hpp"
+#include "svnqt/info_entry.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+namespace svn
+{
+ /**
+ * Subversion status API. This class wraps around
+ * @a svn_wc_status_t.
+ *
+ * @see svn_wc.hpp
+ * @see svn_wc_status_t
+ */
+ class Status_private;
+
+ class SVNQT_EXPORT Status
+ {
+ public:
+ /**
+ * copy constructor
+ */
+ Status (const Status & src);
+
+ /**
+ * default constructor
+ *
+ * @param path path for this status entry
+ * @param status status entry
+ */
+ Status (const QString&path=QString::null, svn_wc_status2_t * status = NULL);
+ /**
+ * default constructor
+ *
+ * @param path path for this status entry
+ * @param status status entry
+ */
+ Status (const char*path, svn_wc_status2_t * status = NULL);
+ /**
+ * converting constructor
+ */
+ Status(const QString&path,const DirEntryPtr&src);
+ /**
+ * converting constructor
+ */
+ Status(const QString&path,const InfoEntry&src);
+
+ /**
+ * destructor
+ */
+ virtual ~Status ();
+
+ /**
+ * @return path of status entry
+ */
+ const QString&
+ path () const;
+
+ /**
+ * @return entry for this path
+ * @retval entry.isValid () = false item is not versioned
+ */
+ const Entry&
+ entry () const;
+ /**
+ * @return file status property enum of the "textual" component.
+ */
+ svn_wc_status_kind
+ textStatus () const;
+
+ /**
+ * @return file status property enum of the "property" component.
+ */
+ svn_wc_status_kind
+ propStatus () const;
+
+ /**
+ * @retval TRUE if under version control
+ */
+ bool
+ isVersioned () const;
+
+ /**
+ * @retval TRUE if under version control and not ignored
+ */
+ bool
+ isRealVersioned()const;
+
+ /**
+ * @retval TRUE if under version control and local modified
+ */
+ bool
+ isModified()const;
+
+ /**
+ * @retval TRUE if locked
+ */
+ bool
+ isLocked () const;
+
+ /**
+ * @retval TRUE if copied
+ */
+ bool
+ isCopied () const;
+
+ /**
+ * @retval TRUE if switched
+ */
+ bool
+ isSwitched () const;
+ /**
+ * @return the entry's text status in the repository
+ */
+ svn_wc_status_kind
+ reposTextStatus () const;
+ /**
+ * @return the entry's prop status in the repository
+ */
+ svn_wc_status_kind
+ reposPropStatus () const;
+
+ const LockEntry&
+ lockEntry () const;
+
+ bool
+ validReposStatus()const;
+
+ bool
+ validLocalStatus()const;
+
+
+ /**
+ * assignment operator
+ */
+ Status &
+ operator = (const Status &);
+ private:
+ Status_private*m_Data;
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/stringarray.cpp b/src/svnqt/stringarray.cpp
new file mode 100644
index 0000000..bdac55b
--- /dev/null
+++ b/src/svnqt/stringarray.cpp
@@ -0,0 +1,121 @@
+/***************************************************************************
+ * Copyright (C) 2006-2008 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "svnqt/stringarray.hpp"
+#include "svnqt/pool.hpp"
+
+#include <svn_types.h>
+// apr api
+#include <apr_pools.h>
+#include <apr_strings.h>
+
+/*!
+ \fn svn::StringArray::StringArray()
+ */
+ svn::StringArray::StringArray()
+ :m_content()
+{
+ setNull(true);
+}
+
+
+/*!
+ \fn svn::StringArray::StringArray(const QStringList&)
+ */
+svn::StringArray::StringArray(const QStringList&aList)
+ :m_content(aList)
+{
+ setNull(false);
+}
+
+/*!
+ \fn svn::StringArray::StringArray(const apr_array_header_t * apr_targets)
+ */
+svn::StringArray::StringArray(const apr_array_header_t * apr_targets)
+ :m_content()
+{
+ int i;
+ for (i = 0; i < apr_targets->nelts; i++)
+ {
+ const char ** target =
+ &APR_ARRAY_IDX (apr_targets, i, const char *);
+
+ m_content.push_back (QString::FROMUTF8(*target));
+ }
+}
+
+
+/*!
+ \fn svn::StringArray::size()const
+ */
+size_t svn::StringArray::size()const
+{
+ if (isNull()) {
+ return 0;
+ }
+ return m_content.size ();
+}
+
+
+/*!
+ \fn svn::StringArray::operator[](size_t which)
+ */
+const QString& svn::StringArray::operator[](size_t which)
+{
+ return m_content[which];
+}
+
+
+/*!
+ \fn svn::StringArray::array (const Pool & pool) const
+ */
+apr_array_header_t * svn::StringArray::array (const Pool & pool) const
+{
+ if (isNull()) {
+ return 0;
+ }
+ QStringList::const_iterator it;
+
+ apr_pool_t *apr_pool = pool.pool ();
+ apr_array_header_t *apr_targets =
+ apr_array_make (apr_pool,m_content.size(),sizeof (const char *));
+
+ for (it = m_content.begin (); it != m_content.end (); it++)
+ {
+ QByteArray s = (*it).TOUTF8();
+ char * t2 = apr_pstrndup (apr_pool,s,s.size());
+
+ (*((const char **) apr_array_push (apr_targets))) = t2;
+ }
+ return apr_targets;
+}
+
+bool svn::StringArray::isNull()const
+{
+ return m_isNull;
+}
+
+void svn::StringArray::setNull(bool _n)
+{
+ if (_n) {
+ m_content.clear();
+ }
+ m_isNull = _n;
+}
diff --git a/src/svnqt/stringarray.hpp b/src/svnqt/stringarray.hpp
new file mode 100644
index 0000000..285f500
--- /dev/null
+++ b/src/svnqt/stringarray.hpp
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * Copyright (C) 2006-2008 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef _STRING_ARRAY_HPP
+#define _STRING_ARRAY_HPP
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/svnqttypes.hpp"
+
+#include <qglobal.h>
+#if QT_VERSION < 0x040000
+#include <qstringlist.h>
+#else
+#include <QtCore>
+#include <QStringList>
+#endif
+
+// apr api
+#include "apr_tables.h"
+
+namespace svn
+{
+ // forward declarations
+ class Pool;
+
+ /** Handle array of const char * in a c++ like way */
+ class SVNQT_EXPORT StringArray
+ {
+ protected:
+ QStringList m_content;
+ bool m_isNull;
+
+ public:
+ StringArray();
+ StringArray(const QStringList&);
+ StringArray(const apr_array_header_t * apr_targets);
+ size_t size()const;
+ const QString& operator[](size_t which);
+ /**
+ * Returns an apr array containing char*.
+ *
+ * @param pool Pool used for conversion
+ */
+ apr_array_header_t * array (const Pool & pool) const;
+ /** content of array
+ * @return const reference to data, may used for searches.
+ */
+ const QStringList& data() const {return m_content;}
+
+ /** if array should return 0 instead of empty array */
+ bool isNull()const;
+ void setNull(bool _n);
+ };
+}
+
+#endif
diff --git a/src/svnqt/svnfilestream.cpp b/src/svnqt/svnfilestream.cpp
new file mode 100644
index 0000000..2803ef4
--- /dev/null
+++ b/src/svnqt/svnfilestream.cpp
@@ -0,0 +1,134 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "svnfilestream.hpp"
+
+#include <qfile.h>
+
+namespace svn {
+
+namespace stream {
+
+#if QT_VERSION < 0x040000
+typedef int openmode;
+#define READONLY IO_ReadOnly
+#define WRITEONLY IO_WriteOnly
+#else
+typedef QIODevice::OpenMode openmode;
+#define READONLY QIODevice::ReadOnly
+#define WRITEONLY QIODevice::WriteOnly
+#endif
+
+class SVNQT_NOEXPORT SvnFileStream_private
+{
+public:
+ SvnFileStream_private(const QString&fn,openmode mode);
+ virtual ~SvnFileStream_private();
+
+ QString m_FileName;
+ QFile m_File;
+};
+
+SvnFileStream_private::SvnFileStream_private(const QString&fn,openmode mode)
+ : m_FileName(fn),m_File(fn)
+{
+ m_File.open(mode);
+}
+
+SvnFileStream_private::~SvnFileStream_private()
+{
+}
+
+SvnFileOStream::SvnFileOStream(const QString&fn,svn_client_ctx_t*ctx)
+ :SvnStream(false,true,ctx)
+{
+ m_FileData = new SvnFileStream_private(fn,WRITEONLY);
+ if (!m_FileData->m_File.isOpen()) {
+ setError(m_FileData->m_File.errorString());
+ }
+}
+
+
+SvnFileOStream::~SvnFileOStream()
+{
+ delete m_FileData;
+}
+
+
+bool SvnFileOStream::isOk() const
+{
+ return m_FileData->m_File.isOpen();
+}
+
+long SvnFileOStream::write(const char* data, const unsigned long max)
+{
+ if (!m_FileData->m_File.isOpen()) {
+ return -1;
+ }
+#if QT_VERSION < 0x040000
+ long res = m_FileData->m_File.writeBlock(data,max);
+#else
+ long res = m_FileData->m_File.write(data,max);
+#endif
+ if (res<0) {
+ setError(m_FileData->m_File.errorString());
+ }
+ return res;
+}
+
+SvnFileIStream::SvnFileIStream(const QString&fn,svn_client_ctx_t*ctx)
+ :SvnStream(true,false,ctx)
+{
+ m_FileData = new SvnFileStream_private(fn,READONLY);
+ if (!m_FileData->m_File.isOpen()) {
+ setError(m_FileData->m_File.errorString());
+ }
+}
+
+
+SvnFileIStream::~SvnFileIStream()
+{
+ delete m_FileData;
+}
+
+
+bool SvnFileIStream::isOk() const
+{
+ return m_FileData->m_File.isOpen();
+}
+
+long SvnFileIStream::read(char* data, const unsigned long max)
+{
+ if (!m_FileData->m_File.isOpen()) {
+ return -1;
+ }
+#if QT_VERSION < 0x040000
+ long res = m_FileData->m_File.readBlock(data,max);
+#else
+ long res = m_FileData->m_File.read(data,max);
+#endif
+ if (res<0) {
+ setError(m_FileData->m_File.errorString());
+ }
+ return res;
+}
+
+}
+
+}
diff --git a/src/svnqt/svnfilestream.hpp b/src/svnqt/svnfilestream.hpp
new file mode 100644
index 0000000..d64e1cc
--- /dev/null
+++ b/src/svnqt/svnfilestream.hpp
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef SVN_STREAMSVNFILESTREAM_HPP
+#define SVN_STREAMSVNFILESTREAM_HPP
+
+#include "svnstream.hpp"
+
+namespace svn {
+
+namespace stream {
+
+class SvnFileStream_private;
+
+/**
+ @author Rajko Albrecht <ral@alwins-world.de>
+ @short Writeonly filestream
+*/
+class SVNQT_EXPORT SvnFileOStream : public SvnStream
+{
+public:
+ SvnFileOStream(const QString&fn,svn_client_ctx_t*ctx=0);
+
+ virtual ~SvnFileOStream();
+
+ virtual bool isOk() const;
+ virtual long write(const char* data, const unsigned long max);
+private:
+ SvnFileStream_private*m_FileData;
+};
+
+/**
+ @author Rajko Albrecht <ral@alwins-world.de>
+ @short Readonly filestream
+*/
+class SVNQT_EXPORT SvnFileIStream : public SvnStream
+{
+public:
+ SvnFileIStream(const QString&fn,svn_client_ctx_t*ctx=0);
+
+ virtual ~SvnFileIStream();
+ virtual bool isOk() const;
+ virtual long read(char* data, const unsigned long max);
+
+private:
+ SvnFileStream_private*m_FileData;
+};
+
+}
+
+}
+
+#endif
diff --git a/src/svnqt/svnqt_defines.hpp.in b/src/svnqt/svnqt_defines.hpp.in
new file mode 100644
index 0000000..6281d42
--- /dev/null
+++ b/src/svnqt/svnqt_defines.hpp.in
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef _SVNQT_DEFINES_H
+#define _SVNQT_DEFINES_H
+
+/* defines if we setup against a compiler with working "-fvisibility=hidden" */
+#define SVNQT_EXPORT @_SVNQT_EXPORT@
+#define SVNQT_NOEXPORT @_SVNQT_NOEXPORT@
+
+/* cmake trick: so we make sure that the define in installs
+ is always set as in library used at build time
+ */
+#define TOUTF8 @TOUTF8@
+#define FROMUTF8 @FROMUTF8@
+#define QLIST @QLIST@
+#define TOASCII @TOASCII@
+#define HOMEDIR @HOMEDIR@
+#define QLONG @QLONG@
+
+#define SVNQT_SIZE_UNKNOWN QLONG(-1)
+
+/* the difference between qt3 and qt4 is too much... :( */
+class QSqlDatabase;
+typedef @QDATABASE@ QDataBase;
+#endif
diff --git a/src/svnqt/svnqttypes.hpp b/src/svnqt/svnqttypes.hpp
new file mode 100644
index 0000000..b3c6381
--- /dev/null
+++ b/src/svnqt/svnqttypes.hpp
@@ -0,0 +1,104 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Rajko Albrecht ral@alwins-world.de *
+ * http://kdesvn.alwins-world.de/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef _SVNQT_TYPES_HPP
+#define _SVNQT_TYPES_HPP
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/shared_pointer.hpp"
+
+// qt
+#include <qglobal.h>
+
+#if QT_VERSION < 0x040000
+ #include <qstring.h>
+ #include <qpair.h>
+ #include <qvaluelist.h>
+ #include <qmap.h>
+#else
+ #include <QtCore>
+#endif
+
+namespace svn
+{
+ // forward declarations
+ class AnnotateLine;
+ class Context;
+ class DirEntry;
+ class InfoEntry;
+ class LogEntry;
+ class Revision;
+ class Status;
+ class Targets;
+ class Path;
+ class StringArray;
+
+ typedef QLIST<AnnotateLine> AnnotatedFile;
+
+ typedef SharedPointer<DirEntry> DirEntryPtr;
+ typedef QLIST<DirEntryPtr> DirEntries;
+ typedef QLIST<InfoEntry> InfoEntries;
+ /// simple list of log entries
+ typedef QLIST<LogEntry> LogEntries;
+ /// shared_pointer for LogEntriesMap
+ typedef SharedPointer<LogEntries> LogEntriesPtr;
+
+ /// map of logentries - key is revision
+ typedef QMap<long,LogEntry> LogEntriesMap;
+ /// shared_pointer for LogEntriesMap
+ typedef SharedPointer<LogEntriesMap> LogEntriesMapPtr;
+
+ typedef SharedPointer<Status> StatusPtr;
+ typedef QLIST<StatusPtr> StatusEntries;
+ typedef QLIST<Revision> Revisions;
+
+ /** Range of Revision */
+ typedef QPair<Revision,Revision> RevisionRange;
+ /** list of revision ranges */
+ typedef QLIST<RevisionRange> RevisionRanges;
+
+ /// map of property names to values
+ typedef QMap<QString,QString> PropertiesMap;
+ /// pair of path, PropertiesMap
+ typedef QPair<QString, PropertiesMap> PathPropertiesMapEntry;
+ /// vector of path, Properties pairs
+ typedef QLIST<PathPropertiesMapEntry> PathPropertiesMapList;
+ /// shared pointer for properties
+ typedef SharedPointer<PathPropertiesMapList> PathPropertiesMapListPtr;
+
+ typedef QLIST<Path> Pathes;
+
+ //! Mapper enum for svn_depth_t
+ /*!
+ * Until subversion prior 1.5 is supported by this lib we must hide the svn_depth_t enum from interface.
+ * \since subversion 1.5 / svnqt 1.0
+ * \sa svn_depth_t
+ */
+ enum Depth {
+ DepthUnknown,
+ DepthExclude,
+ DepthEmpty,
+ DepthFiles,
+ DepthImmediates,
+ DepthInfinity
+ };
+}
+
+#endif
diff --git a/src/svnqt/svnstream.cpp b/src/svnqt/svnstream.cpp
new file mode 100644
index 0000000..e3b6014
--- /dev/null
+++ b/src/svnqt/svnstream.cpp
@@ -0,0 +1,263 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "svnqt/svnstream.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/apr.hpp"
+
+// Subversion api
+#include "svn_client.h"
+
+#include <qbuffer.h>
+#include <qdatetime.h>
+#include <qfile.h>
+
+#define MAX_TIME 300
+
+namespace svn {
+
+namespace stream {
+class SVNQT_NOEXPORT SvnStream_private
+{
+public:
+ SvnStream_private(){m_Stream=0;m_LastError="";_context=0;cancel_timeout.start();}
+ ~SvnStream_private(){qDebug("Time elapsed: %i ",cancel_timeout.elapsed());}
+
+ static svn_error_t * stream_write(void*baton,const char*data,apr_size_t*len);
+ static svn_error_t * stream_read(void*baton,char*data,apr_size_t*len);
+
+ Pool m_Pool;
+ svn_stream_t * m_Stream;
+ QString m_LastError;
+
+ svn_client_ctx_t* _context;
+ QTime cancel_timeout;
+};
+
+svn_error_t * SvnStream_private::stream_read(void*baton,char*data,apr_size_t*len)
+{
+ SvnStream*b = (SvnStream*)baton;
+ svn_client_ctx_t*ctx = b->context();
+
+ if (ctx&&ctx->cancel_func) {
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ }
+
+ long res = b->isOk()?b->read(data,*len):-1;
+
+ if (res<0) {
+ *len = 0;
+ return svn_error_create(SVN_ERR_MALFORMED_FILE,0L,b->lastError().TOUTF8());
+ }
+ *len = res;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t * SvnStream_private::stream_write(void*baton,const char*data,apr_size_t*len)
+{
+ SvnStream*b = (SvnStream*)baton;
+ svn_client_ctx_t*ctx = b->context();
+
+ if (ctx&&ctx->cancel_func&&b->cancelElapsed()>50) {
+ qDebug("Check cancel");
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+ b->cancelTimeReset();
+ }
+
+ long res = b->isOk()?b->write(data,*len):-1;
+ if (res<0) {
+ *len = 0;
+ return svn_error_create(SVN_ERR_MALFORMED_FILE,0L,b->lastError().TOUTF8());
+ }
+ *len = res;
+ return SVN_NO_ERROR;
+}
+
+SvnStream::SvnStream(bool read, bool write,svn_client_ctx_t * ctx)
+{
+ m_Data = new SvnStream_private;
+ m_Data->m_Stream = svn_stream_create(this,m_Data->m_Pool);
+ m_Data->_context = ctx;
+ if (read) {
+ svn_stream_set_read(m_Data->m_Stream,SvnStream_private::stream_read);
+ }
+ if (write) {
+ svn_stream_set_write(m_Data->m_Stream,SvnStream_private::stream_write);
+ }
+}
+
+SvnStream::SvnStream()
+{
+}
+
+SvnStream::~SvnStream()
+{
+ delete m_Data;
+}
+
+int SvnStream::cancelElapsed()const
+{
+ return m_Data->cancel_timeout.elapsed();
+}
+
+void SvnStream::cancelTimeReset()
+{
+ m_Data->cancel_timeout.restart();
+}
+
+SvnStream::operator svn_stream_t* ()const
+{
+ return m_Data->m_Stream;
+}
+
+svn_client_ctx_t * SvnStream::context()
+{
+ return m_Data->_context;
+}
+
+long SvnStream::write(const char*,const unsigned long)
+{
+ m_Data->m_LastError = "Write not supported with that stream";
+ return -1;
+}
+
+long SvnStream::read(char*,const unsigned long )
+{
+ m_Data->m_LastError = "Read not supported with that stream";
+ return -1;
+}
+
+const QString&SvnStream::lastError()const
+{
+ return m_Data->m_LastError;
+}
+
+void SvnStream::setError(const QString&aError)const
+{
+ m_Data->m_LastError = aError;
+}
+
+#if QT_VERSION < 0x040000
+void SvnStream::setError(int ioError)const
+{
+ switch (ioError) {
+ case IO_Ok:
+ setError("Operation was successfull.");
+ break;
+ case IO_ReadError:
+ setError("Could not read from device");
+ break;
+ case IO_WriteError:
+ setError("Could not write to device");
+ break;
+ case IO_FatalError:
+ setError("A fatal unrecoverable error occurred.");
+ break;
+ case IO_OpenError:
+ setError("Could not open device or stream.");
+ break;
+ case IO_AbortError:
+ setError("The operation was unexpectedly aborted.");
+ break;
+ case IO_TimeOutError:
+ setError("The operation timed out.");
+ break;
+ case IO_UnspecifiedError:
+ setError("An unspecified error happened on close.");
+ break;
+ default:
+ setError("Unknown error happend.");
+ break;
+ }
+}
+#endif
+
+class SvnByteStream_private {
+public:
+ SvnByteStream_private();
+ virtual ~SvnByteStream_private(){}
+
+ QByteArray m_Content;
+ QBuffer mBuf;
+};
+
+#if QT_VERSION < 0x040000
+SvnByteStream_private::SvnByteStream_private()
+ :mBuf(m_Content)
+{
+ mBuf.open(IO_WriteOnly);
+}
+#else
+SvnByteStream_private::SvnByteStream_private()
+ :mBuf(&m_Content, 0)
+{
+ mBuf.open(QFile::WriteOnly);
+}
+#endif
+
+/* ByteStream implementation start */
+SvnByteStream::SvnByteStream(svn_client_ctx_t * ctx)
+ : SvnStream(false,true,ctx)
+{
+ m_ByteData = new SvnByteStream_private;
+ if (!m_ByteData->mBuf.isOpen()) {
+#if QT_VERSION < 0x040000
+ setError(m_ByteData->mBuf.status());
+#else
+ setError(m_ByteData->mBuf.errorString());
+#endif
+ }
+}
+
+SvnByteStream::~SvnByteStream()
+{
+ delete m_ByteData;
+}
+
+long SvnByteStream::write(const char*aData,const unsigned long max)
+{
+#if QT_VERSION < 0x040000
+ long i = m_ByteData->mBuf.writeBlock(aData,max);
+ if (i<0) {
+ setError(m_ByteData->mBuf.status());
+ }
+#else
+ long i = m_ByteData->mBuf.write(aData,max);
+ if (i<0) {
+ setError(m_ByteData->mBuf.errorString());
+ }
+#endif
+ return i;
+}
+
+QByteArray SvnByteStream::content()const
+{
+ return m_ByteData->mBuf.buffer();
+}
+
+bool SvnByteStream::isOk()const
+{
+ return m_ByteData->mBuf.isOpen();
+}
+
+/* ByteStream implementation end */
+
+} // namespace stream
+
+} // namespace svn
diff --git a/src/svnqt/svnstream.hpp b/src/svnqt/svnstream.hpp
new file mode 100644
index 0000000..89276c8
--- /dev/null
+++ b/src/svnqt/svnstream.hpp
@@ -0,0 +1,164 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef SVNSVNSTREAM_HPP
+#define SVNSVNSTREAM_HPP
+
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qstring.h>
+
+#include <svn_io.h>
+struct svn_client_ctx_t;
+
+namespace svn {
+
+namespace stream {
+class SvnStream_private;
+
+/**
+ @author Rajko Albrecht <ral@alwins-world.de>
+ @short wrapper class around the svn_stream_t structure
+*/
+class SVNQT_EXPORT SvnStream{
+ friend class SvnStream_private;
+public:
+ //! Constructor
+ /*!
+ * Setup a svn_stream_t and holds a required pool. The stream will freed
+ * when deleting this object.
+ * \param readit set readable
+ * \param writeit set writable
+ * \param ctx a client context for calls to cancel_func inside. you should this only set with functions not using it itself
+ * like svn_client_cat2:
+ */
+ SvnStream(bool readit, bool writeit, svn_client_ctx_t * ctx = 0);
+ //! frees all structures and releases memory pool.
+ virtual ~SvnStream();
+
+ //! operator returning transparent a svn_stream_t structure
+ /*!
+ \return a svn_stream_t structure for use with subversion api.
+ */
+ operator svn_stream_t* ()const;
+
+ //! write operation
+ /*!
+ Write data FROM subversion to the class behind. Eg., data comes from
+ subversion-api and this method has to do something with it (printing on a window, writing to a file)
+ This implementation always returns -1 (eg, error), must reimplemented for real usage.
+ \param data the data to written
+ \param max maximum data to write
+ \return should return the amount of data real written, in case of error must return -1
+ \sa setError(int ioError), setError(const QString&error), read(char*data,const unsigned long max)
+ */
+ virtual long write(const char*data,const unsigned long max);
+ //! read operation
+ /*! implements the wrapper for svn_stream_read, eg. data are read FROM class (eg, file, string or whatever)
+ into subversion-api. This implementation always returns -1 (eg, error), must reimplemented for real usage.
+ \param data target array where to store the read
+ \param max maximum byte count to read
+ \return amount of data read or -1 in case of error
+ \sa setError(int ioError), setError(const QString&error), write(const char*data,const unsigned long max)
+ */
+ virtual long read(char*data,const unsigned long max);
+
+ //! returns the error set
+ /*!
+ \return a human readable message about the reason the last operation failed.
+ */
+ virtual const QString& lastError()const;
+ //! is that stream usable
+ /*!
+ Gives information about if the stream object is usable. May if the file is real open or such.
+ \return true if stream is usable, false if not.
+ */
+ virtual bool isOk()const = 0;
+
+ svn_client_ctx_t * context();
+
+protected:
+ //! set a human readable errormessage
+ /*!
+ This message may printed to the user and will checked if one of the stream-operations failed. So should set from
+ write and/or read if them will return -1 (for error)
+ \param error the errormessage assigned.
+ */
+ virtual void setError(const QString&error)const;
+ //! set the internal error
+ /*! \param ioError error code from QIODevide::status
+ */
+#if QT_VERSION < 0x040000
+ virtual void setError(int ioError)const;
+#endif
+
+protected:
+ int cancelElapsed()const;
+ void cancelTimeReset();
+
+private:
+ SvnStream_private*m_Data;
+ /* disable default contructor */
+ SvnStream();
+};
+
+class SvnByteStream_private;
+
+//! a class let subversion print into a QByteArray
+class SVNQT_EXPORT SvnByteStream:public SvnStream
+{
+public:
+ //! constructor
+ /*!
+ creates internal buffer
+ * \param ctx a client context for calls to cancel_func inside. you should this only set with functions not using it itself
+ * like svn_client_cat2:
+ */
+ SvnByteStream(svn_client_ctx_t * ctx = 0);
+ //! release internal buffer
+ virtual ~SvnByteStream();
+ //! fill internal buffer with data
+ /*!
+ stores the data written into the internal buffer.
+ \param data data to store
+ \param max length of data to store
+ \return data real stored or -1 if error.
+ */
+ virtual long write(const char*data,const unsigned long max);
+
+ //! return the data stored
+ /*!
+ \return the internal stored data
+ */
+ QByteArray content()const;
+ //! checks if the buffer is usable.
+ /*!
+ * \return true if data may written, false if not, in that case a errormessage will set.
+ */
+ virtual bool isOk()const;
+
+private:
+ SvnByteStream_private*m_ByteData;
+};
+
+} // namespace stream
+
+} // namespace svn
+
+#endif
diff --git a/src/svnqt/targets.cpp b/src/svnqt/targets.cpp
new file mode 100644
index 0000000..6e2fced
--- /dev/null
+++ b/src/svnqt/targets.cpp
@@ -0,0 +1,170 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// subversion api
+#include "svn_types.h"
+
+// apr api
+#include "apr_pools.h"
+#include "apr_strings.h"
+
+// svncpp
+#include "svnqt/targets.hpp"
+#include "svnqt/path.hpp"
+#include "svnqt/pool.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qstringlist.h>
+
+namespace svn
+{
+ Targets::Targets (const Pathes & targets)
+ {
+ m_targets = targets;
+ }
+
+ Targets::Targets(const QStringList&targets)
+ {
+ m_targets.clear();
+ for (unsigned int i = 0; i < targets.size();++i) {
+ if (targets[i].isEmpty()) {
+ m_targets.push_back("");
+ } else {
+ m_targets.push_back(targets[i]);
+ }
+ }
+ }
+
+ Targets::Targets (const apr_array_header_t * apr_targets)
+ {
+ int i;
+
+ m_targets.clear ();
+ //m_targets.reserve (apr_targets->nelts);
+
+ for (i = 0; i < apr_targets->nelts; i++)
+ {
+ const char ** target =
+ &APR_ARRAY_IDX (apr_targets, i, const char *);
+
+ m_targets.push_back (Path (*target));
+ }
+ }
+
+ Targets::Targets (const Targets & targets)
+ {
+ m_targets = targets.targets ();
+ }
+
+ Targets::Targets (const QString& target)
+ {
+ if (!target.isEmpty()) {
+ m_targets.push_back(target);
+ }
+ }
+
+ Targets::Targets (const Path& target)
+ {
+ if (!target.cstr().isEmpty()) {
+ m_targets.push_back(target);
+ }
+ }
+
+ Targets::Targets (const char* target)
+ {
+ if (target) {
+ m_targets.push_back(QString::FROMUTF8(target));
+ }
+ }
+
+ Targets::~Targets ()
+ {
+ }
+
+ apr_array_header_t *
+ Targets::array (const Pool & pool) const
+ {
+ Pathes::const_iterator it;
+
+ apr_pool_t *apr_pool = pool.pool ();
+ apr_array_header_t *apr_targets =
+ apr_array_make (apr_pool,
+ m_targets.size(),
+ sizeof (const char *));
+
+ for (it = m_targets.begin (); it != m_targets.end (); it++)
+ {
+ QByteArray s = (*it).path().TOUTF8();
+
+ char * t2 =
+ apr_pstrndup (apr_pool,s,s.size());
+
+ (*((const char **) apr_array_push (apr_targets))) = t2;
+ }
+
+ return apr_targets;
+ }
+
+ const Pathes &
+ Targets::targets () const
+ {
+ return m_targets;
+ }
+
+ size_t
+ Targets::size () const
+ {
+ return m_targets.size ();
+ }
+
+ const Path& Targets::operator [](size_t which)const
+ {
+ return m_targets[which];
+ }
+
+ const Path
+ Targets::target (unsigned int which) const
+ {
+ if (m_targets.size () > which)
+ {
+ return m_targets[which];
+ }
+ else
+ {
+ return Path();
+ }
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/targets.hpp b/src/svnqt/targets.hpp
new file mode 100644
index 0000000..06cef77
--- /dev/null
+++ b/src/svnqt/targets.hpp
@@ -0,0 +1,168 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_TARGETS_HPP_
+#define _SVNCPP_TARGETS_HPP_
+
+#include "svnqt/svnqt_defines.hpp"
+#include "svnqt/svnqttypes.hpp"
+
+#include <qglobal.h>
+#if QT_VERSION < 0x040000
+#include <qvaluelist.h>
+#else
+#include <QtCore>
+#endif
+
+// apr api
+#include "apr_tables.h"
+
+class QStringList;
+
+namespace svn
+{
+ // forward declarations
+ class Pool;
+
+ /**
+ * Encapsulation for Subversion target arrays handling
+ */
+ class SVNQT_EXPORT Targets
+ {
+ public:
+ /**
+ * Constructor
+ *
+ * @param targets vector of paths
+ */
+ Targets (const Pathes & targets);
+
+ /**
+ * Constructor
+ * @param path a single paths
+ */
+ Targets (const Path & targets);
+
+ /**
+ * Constructor from an APR array containing
+ * char *.
+ *
+ * @param targets APR array header
+ */
+ Targets (const apr_array_header_t * targets);
+
+ /**
+ * Constructor. Initializes list with just
+ * one entry
+ *
+ * @param target
+ */
+ Targets (const QString& target = QString::null);
+ /**
+ * Constructor. Initializes list with just
+ * one entry
+ *
+ * @param target
+ */
+ Targets (const char * target);
+ /**
+ * Constructor. Convert stringlist into target list.
+ * @param targets
+ */
+ Targets(const QStringList&targets);
+
+ /**
+ * Copy Constructor
+ *
+ * @param targets Source
+ */
+ Targets (const Targets & targets);
+
+ /**
+ * Destructor
+ */
+ virtual ~Targets ();
+
+ /**
+ * Returns an apr array containing
+ * char *.
+ *
+ * @param pool Pool used for conversion
+ */
+ apr_array_header_t *
+ array (const Pool & pool) const;
+
+ /**
+ * Returns a vector of paths
+ *
+ * @return vector of paths
+ */
+ const Pathes &
+ targets() const;
+
+ /**
+ * @return the number of targets
+ */
+ size_t size () const;
+
+ /**
+ * operator to return the vector
+ *
+ * @return vector with targets
+ */
+ operator const Pathes & () const
+ {
+ return m_targets;
+ }
+
+ const Path& operator [](size_t which)const;
+ /**
+ * returns one single target.
+ * the first in the vector, if no parameter given if there are more
+ * than one. if there is no target or parameter > then stored pathes returns
+ * an empty path
+ * \param which which item we want
+ * @return single path
+ */
+ const Path
+ target(unsigned int which = 0) const;
+
+
+ private:
+ Pathes m_targets;
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/testmain.cpp b/src/svnqt/testmain.cpp
new file mode 100644
index 0000000..13ae286
--- /dev/null
+++ b/src/svnqt/testmain.cpp
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "client.hpp"
+#include "repository.hpp"
+#include "context.hpp"
+#include "datetime.hpp"
+
+#include <qdatastream.h>
+
+int main(int,char**)
+{
+ svn::Client::getobject(0,0);
+ svn::repository::Repository rep(0L);
+ svn::ContextP myContext = new svn::Context();
+
+ QByteArray tout;
+#if QT_VERSION < 0x040000
+ QDataStream out(tout,IO_WriteOnly);
+#endif
+ svn::Client*m_Svnclient = svn::Client::getobject(0,0);
+ svn::ContextP m_CurrentContext = new svn::Context();
+ m_Svnclient->setContext(m_CurrentContext);
+ bool gotit = true;
+ svn::LogEntriesMap m_OldHistory;
+
+ try {
+ m_Svnclient->log("http://www.alwins-world.de/repos/kdesvn/trunk",svn::Revision::HEAD,20,m_OldHistory,svn::Revision::UNDEFINED,true,false,0);
+ } catch (svn::ClientException ce) {
+ gotit = false;
+ }
+#if QT_VERSION < 0x040000
+ if (gotit) {
+ out << m_OldHistory;
+ svn::LogEntriesMap m_NewHistory;
+ QDataStream inp(tout,IO_ReadOnly);
+ inp >> m_NewHistory;
+
+ svn::LogEntriesMap::Iterator it;
+ for (it=m_NewHistory.begin();it!=m_NewHistory.end();++it) {
+ qDebug("%lu %s %s",it.key(),it.data().author.ascii(),it.data().message.ascii());
+ }
+ }
+#endif
+ return 1;
+}
diff --git a/src/svnqt/tests/CMakeLists.txt b/src/svnqt/tests/CMakeLists.txt
new file mode 100644
index 0000000..8aef2d5
--- /dev/null
+++ b/src/svnqt/tests/CMakeLists.txt
@@ -0,0 +1,23 @@
+SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
+
+MACRO(BUILD_TEST tname)
+ SET(${tname}-src ${tname}.cpp)
+ IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${tname}.h)
+ SET(${tname}-src ${${tname}-src} ${tname}.h)
+ ENDIF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${tname}.h)
+ ADD_EXECUTABLE(${tname} ${${tname}-src})
+ TARGET_LINK_LIBRARIES(${tname} ${svnqt-name} ${QT_LIBRARIES})
+ ADD_TEST(${tname} ${CMAKE_CURRENT_BINARY_DIR}/${tname})
+ENDMACRO(BUILD_TEST)
+
+IF (BUILD_TESTS)
+ CONFIGURE_FILE(
+ ${CMAKE_CURRENT_SOURCE_DIR}/testconfig.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/testconfig.h
+ )
+ ADD_TEST(rmrepo "/bin/rm" "-rvf" "${CMAKE_CURRENT_BINARY_DIR}/repo")
+ ADD_TEST(rmco "/bin/rm" "-rvf" "${CMAKE_CURRENT_BINARY_DIR}/co")
+ BUILD_TEST(crepo)
+ BUILD_TEST(lsdir)
+ BUILD_TEST(ckpath)
+ENDIF(BUILD_TESTS)
diff --git a/src/svnqt/tests/ckpath.cpp b/src/svnqt/tests/ckpath.cpp
new file mode 100644
index 0000000..ca4fe3e
--- /dev/null
+++ b/src/svnqt/tests/ckpath.cpp
@@ -0,0 +1,24 @@
+#include "src/svnqt/path.hpp"
+#include <iostream>
+
+int main(int,char**)
+{
+ svn::Path pa("/test/foo/bar/");
+ if (pa.path()!=QString("/test/foo/bar")) {
+ std::cout << "No cleanup of components" << std::endl;
+ return -1;
+ }
+ pa.removeLast();
+ if (pa.path()!=QString("/test/foo")) {
+ std::cout<<"removeLast didn't work." << std::endl;
+ return -1;
+ }
+ unsigned j = 0;
+ while (pa.length()>0) {
+ std::cout << pa.path() << std::endl;
+ pa.removeLast();
+ ++j;
+ }
+ return 0;
+}
+
diff --git a/src/svnqt/tests/crepo.cpp b/src/svnqt/tests/crepo.cpp
new file mode 100644
index 0000000..604e4e9
--- /dev/null
+++ b/src/svnqt/tests/crepo.cpp
@@ -0,0 +1,63 @@
+#include "src/svnqt/client.hpp"
+#include "src/svnqt/tests/testconfig.h"
+#include "src/svnqt/repository.hpp"
+#include "src/svnqt/repositorylistener.hpp"
+#include "src/svnqt/targets.hpp"
+
+#include "testlistener.h"
+
+#include <iostream>
+#include <unistd.h>
+#include <qstringlist.h>
+
+class Listener:public svn::repository::RepositoryListener
+{
+ public:
+ Listener(){}
+ virtual ~Listener(){}
+ virtual void sendWarning(const QString&msg)
+ {
+ std::cout << msg << std::endl;
+ }
+ virtual void sendError(const QString&msg)
+ {
+ std::cout << msg << std::endl;
+ }
+ virtual bool isCanceld(){return false;}
+};
+
+int main(int,char**)
+{
+ QString p = TESTREPOPATH;
+ Listener ls;
+ svn::repository::Repository rp(&ls);
+ try {
+ rp.CreateOpen(p,"fsfs");
+ } catch (svn::ClientException e) {
+ QString ex = e.msg();
+ std::cout << ex.TOUTF8() << std::endl;
+ return -1;
+ }
+
+ svn::ContextP m_CurrentContext;
+ svn::Client* m_Svnclient;
+ m_Svnclient=svn::Client::getobject(0,0);
+ TestListener tl;
+ m_CurrentContext = new svn::Context();
+ m_CurrentContext->setListener(&tl);
+ p = "file://"+p;
+
+ m_Svnclient->setContext(m_CurrentContext);
+ QStringList s; s.append(p+"/trunk"); s.append(p+"/branches"); s.append(p+"/tags");
+
+ try {
+ m_Svnclient->mkdir(svn::Targets(s),"Test mkdir");
+ m_Svnclient->checkout(p,TESTCOPATH,svn::Revision::HEAD,svn::Revision::HEAD,svn::DepthInfinity,false);
+ } catch (svn::ClientException e) {
+ QString ex = e.msg();
+ std::cout << ex.TOUTF8() << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/svnqt/tests/lsdir.cpp b/src/svnqt/tests/lsdir.cpp
new file mode 100644
index 0000000..c458f31
--- /dev/null
+++ b/src/svnqt/tests/lsdir.cpp
@@ -0,0 +1,78 @@
+
+#include "src/svnqt/client.hpp"
+#include "src/svnqt/tests/testconfig.h"
+#include "src/svnqt/status.hpp"
+#include "src/svnqt/svnqttypes.hpp"
+#include <iostream>
+
+int main(int,char**)
+{
+ svn::ContextP m_CurrentContext;
+ svn::Client* m_Svnclient;
+ m_Svnclient=svn::Client::getobject(0,0);
+ m_CurrentContext = new svn::Context();
+
+ m_Svnclient->setContext(m_CurrentContext);
+ svn::DirEntries dlist;
+
+ QString p = QString("file://%1").arg(TESTREPOPATH);
+ QString l = QString("%1").arg(TESTCOPATH);
+
+ try {
+ dlist = m_Svnclient->list(svn::Path(p),svn::Revision::HEAD,svn::Revision::HEAD,svn::DepthInfinity,true);
+ } catch (svn::ClientException e) {
+ QString ex = e.msg();
+ std::cout << ex.TOUTF8() << std::endl;
+ return -1;
+ }
+ std::cout << "List 1 "<<dlist.size()<<std::endl;
+ for (unsigned int i=0; i < dlist.size();++i) {
+ QDateTime dt = svn::DateTime(dlist[i]->time());
+ std::cout << dlist[i]->name() << " "
+ << dlist[i]->lastAuthor() << " "
+ << dlist[i]->size() << " "
+ << dt.toTime_t() << std::endl;
+ }
+ try {
+ dlist = m_Svnclient->list(svn::Path(p),svn::Revision::HEAD,svn::Revision::HEAD,svn::DepthImmediates,false);
+ } catch (svn::ClientException e) {
+ QString ex = e.msg();
+ std::cout << ex.TOUTF8() << std::endl;
+ return -1;
+ }
+ std::cout << "================"<<std::endl;
+ std::cout << "List 2 "<<dlist.size()<<std::endl;
+ for (unsigned int i=0; i < dlist.size();++i) {
+ QDateTime dt = svn::DateTime(dlist[i]->time());
+ std::cout << dlist[i]->name() << " "
+ << dlist[i]->lastAuthor() << " "
+ << dlist[i]->size() << " "
+ << dt.toTime_t() << std::endl;
+ }
+ std::cout << "================"<<std::endl;
+ svn::StatusEntries slist;
+ try {
+ slist = m_Svnclient->status(svn::Path(p),svn::DepthInfinity,true,true,true,svn::Revision::HEAD,true,false);
+ } catch (svn::ClientException e) {
+ QString ex = e.msg();
+ std::cout << ex.TOUTF8() << std::endl;
+ return -1;
+ }
+ for (unsigned int i=0; i < slist.size();++i) {
+ std::cout << slist[i]->path()<< std::endl;
+ }
+ std::cout << "================"<<std::endl;
+ std::cout << "Second status:"<<std::endl;
+ try {
+ slist = m_Svnclient->status(svn::Path(l),svn::DepthInfinity,true,true,true,svn::Revision::WORKING,true,false);
+ } catch (svn::ClientException e) {
+ QString ex = e.msg();
+ std::cout << ex.TOUTF8() << std::endl;
+ return -1;
+ }
+ for (unsigned int i=0; i < slist.size();++i) {
+ std::cout << slist[i]->path()<< std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/svnqt/tests/testconfig.h.in b/src/svnqt/tests/testconfig.h.in
new file mode 100644
index 0000000..5ffff3e
--- /dev/null
+++ b/src/svnqt/tests/testconfig.h.in
@@ -0,0 +1,7 @@
+#ifndef __TEST_CONFIG_H
+#define __TEST_CONFIG_H
+
+#define TESTREPOPATH "@CMAKE_CURRENT_BINARY_DIR@/repo"
+#define TESTCOPATH "@CMAKE_CURRENT_BINARY_DIR@/co"
+
+#endif
diff --git a/src/svnqt/tests/testlistener.h b/src/svnqt/tests/testlistener.h
new file mode 100644
index 0000000..0c38a43
--- /dev/null
+++ b/src/svnqt/tests/testlistener.h
@@ -0,0 +1,37 @@
+#ifndef _TESTLISTENER_
+#define _TESTLISTENER_
+
+#include "src/svnqt/context_listener.hpp"
+
+class TestListener:public svn::ContextListener
+{
+ public:
+ TestListener(){}
+ virtual ~TestListener(){}
+
+ virtual void contextProgress(long long int current, long long int max){};
+ virtual bool contextSslClientCertPwPrompt (QString &,const QString &, bool &){return false;}
+ virtual bool contextLoadSslClientCertPw(QString&,const QString&){return false;}
+ virtual bool contextSslClientCertPrompt (QString &){return false;}
+ virtual svn::ContextListener::SslServerTrustAnswer
+ contextSslServerTrustPrompt (const SslServerTrustData &,
+ apr_uint32_t & ){return svn::ContextListener::SslServerTrustAnswer();}
+ virtual bool contextGetLogMessage (QString &,const svn::CommitItemList&){return false;}
+ virtual bool contextCancel(){return false;}
+ virtual void contextNotify (const svn_wc_notify_t *){}
+ virtual void contextNotify (const char *,svn_wc_notify_action_t,
+ svn_node_kind_t,
+ const char *,
+ svn_wc_notify_state_t,
+ svn_wc_notify_state_t,
+ svn_revnum_t){}
+ virtual bool contextGetSavedLogin (const QString & realm,QString & username,QString & password){return false;}
+ virtual bool contextGetCachedLogin (const QString & realm,QString & username,QString & password){return false;}
+ virtual bool contextGetLogin (const QString & realm,
+ QString & username,
+ QString & password,
+ bool & maySave){maySave=false;return false;}
+
+};
+
+#endif
diff --git a/src/svnqt/url.cpp b/src/svnqt/url.cpp
new file mode 100644
index 0000000..185f582
--- /dev/null
+++ b/src/svnqt/url.cpp
@@ -0,0 +1,209 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+#if defined( _MSC_VER) && _MSC_VER <= 1200
+#pragma warning( disable: 4786 )// debug symbol truncated
+#endif
+
+
+// svncpp
+#include "pool.hpp"
+#include "url.hpp"
+
+#include <qglobal.h>
+#if QT_VERSION < 0x040000
+#include <qvaluelist.h>
+#else
+#include <QtCore>
+#endif
+
+// subversion api
+#include "svn_ra.h"
+
+namespace svn
+{
+ static const char *
+ VALID_SCHEMAS [] =
+ {
+ "http","https","file",
+ "svn","svn+ssh","svn+http","svn+https","svn+file",
+ "ksvn","ksvn+ssh","ksvn+http","ksvn+https","ksvn+file","ksvn",
+ 0
+ };
+
+ static bool mSchemasInitialized = false;
+#if QT_VERSION < 0x040000
+ QValueList<QString> mSchemas;
+#else
+ QList<QString> mSchemas;
+#endif
+
+ Url::Url () {}
+
+ Url::~Url () {}
+
+ bool Url::isLocal(const QString& url)
+ {
+#if QT_VERSION < 0x040000
+ bool cs = false;
+#else
+ Qt::CaseSensitivity cs=Qt::CaseInsensitive;
+#endif
+ if (
+ url.startsWith("file://",cs) ||
+ url.startsWith("/") ||
+ url.startsWith("svn+file://",cs) ||
+ url.startsWith("ksvn+file://",cs) )
+ {
+ return true;
+ }
+ return false;
+ }
+
+ bool Url::isValid (const QString& url)
+ {
+ QString urlTest(url);
+ unsigned int index = 0;
+ while (VALID_SCHEMAS[index]!=0)
+ {
+ QString schema = QString::FROMUTF8(VALID_SCHEMAS[index]);
+ QString urlComp = urlTest.mid(0, schema.length());
+
+ if (schema == urlComp)
+ {
+ return true;
+ }
+ ++index;
+ }
+
+ return false;
+ }
+
+ QString
+ Url::transformProtokoll(const QString&prot)
+ {
+#if QT_VERSION < 0x040000
+ QString _prot = prot.lower();
+#else
+ QString _prot = prot.toLower();
+#endif
+ if (QString::compare(_prot,"svn+http")==0||
+ QString::compare(_prot,"ksvn+http")==0) {
+ return QString("http");
+ } else if (QString::compare(_prot,"svn+https")==0||
+ QString::compare(_prot,"ksvn+https")==0) {
+ return QString("https");
+ }else if (QString::compare(_prot,"svn+file")==0||
+ QString::compare(_prot,"ksvn+file")==0) {
+ return QString("file");
+ } else if (QString::compare(_prot,"ksvn+ssh")==0) {
+ return QString("svn+ssh");
+ } else if (QString::compare(_prot,"ksvn")==0) {
+ return QString("svn");
+ }
+ return _prot;
+ }
+
+
+ /**
+ * the implementation of the function that pull the supported
+ * url schemas out of the ra layer it rather dirty now since
+ * we are lacking a higher level of abstraction
+ */
+#if QT_VERSION < 0x040000
+ QValueList<QString>
+#else
+ QList<QString>
+#endif
+ Url::supportedSchemas ()
+ {
+ if (mSchemasInitialized)
+ return mSchemas;
+
+ mSchemasInitialized = true;
+ Pool pool;
+ void * ra_baton;
+
+ svn_error_t * error =
+ svn_ra_init_ra_libs (&ra_baton, pool);
+ if (error)
+ return mSchemas;
+
+ svn_stringbuf_t *descr;
+ error =
+ svn_ra_print_ra_libraries (&descr, ra_baton, pool);
+ if (error)
+ return mSchemas;
+
+ // schemas are in the following form:
+ // <schema>:<whitespace><description>\n...
+ // find the f�st :
+ QString descriptions (descr->data);
+ int pos=0;
+ const int not_found = -1;
+ do
+ {
+ const QString tokenStart ("handles '");
+ const QString tokenEnd ("' schem");
+#if QT_VERSION < 0x040000
+ pos = descriptions.find (tokenStart, pos);
+#else
+ pos = descriptions.indexOf( tokenStart, pos );
+#endif
+ if (pos == not_found)
+ break;
+
+ pos += tokenStart.length ();
+
+#if QT_VERSION < 0x040000
+ int posEnd = descriptions.find (tokenEnd, pos);
+#else
+ int posEnd = descriptions.indexOf( tokenEnd, pos );
+#endif
+ if (posEnd == not_found)
+ break;
+
+ // found
+ QString schema (descriptions.mid(pos, posEnd-pos) + ":");
+ mSchemas.push_back (schema);
+
+ // forward to the next newline
+ pos = posEnd + tokenEnd.length ();
+ }
+ while (pos != not_found);
+
+ return mSchemas;
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/url.hpp b/src/svnqt/url.hpp
new file mode 100644
index 0000000..795d4c8
--- /dev/null
+++ b/src/svnqt/url.hpp
@@ -0,0 +1,104 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_URL_H_
+#define _SVNCPP_URL_H_
+
+#include "svnqt/svnqt_defines.hpp"
+
+// qt
+#include <qglobal.h>
+#if QT_VERSION < 0x040000
+
+#include <qstring.h>
+#include <qvaluelist.h>
+
+#else
+
+#include <QtCore>
+
+#endif
+
+
+namespace svn
+{
+ class SVNQT_EXPORT Url
+ {
+ public:
+ /** Constructor */
+ Url ();
+
+ /** Destructor */
+ virtual ~Url ();
+
+ /**
+ * Checks if @a url is valid
+ *
+ * Example of a valid URL:
+ * http://svn.collab.net/repos/svn
+ * Example of an invalid URL:
+ * /home/foo/bar
+ */
+ static bool
+ isValid (const QString& url);
+
+ /**
+ * Checks if @a url points to a local filesystem.
+ *
+ * @return true if url is accessed local without network.
+ */
+ static bool
+ isLocal(const QString& url);
+
+ static QString
+ transformProtokoll(const QString&);
+
+ /**
+ * returns a vector with url schemas that are
+ * supported by svn
+ *
+ * @return vector with entries like "file:", "http:"
+ */
+#if QT_VERSION < 0x040000
+ static QValueList<QString>
+#else
+ static QList<QString>
+#endif
+ supportedSchemas ();
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
+
diff --git a/src/svnqt/version_check.cpp b/src/svnqt/version_check.cpp
new file mode 100644
index 0000000..02f6b10
--- /dev/null
+++ b/src/svnqt/version_check.cpp
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "version_check.hpp"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <svn_version.h>
+#include <svn_client.h>
+
+#include <qstring.h>
+
+namespace svn {
+ static const svn_version_t Linkedtag = {
+ SVN_VER_MAJOR,
+ SVN_VER_MINOR,
+ SVN_VER_PATCH,
+ SVN_VER_NUMTAG
+ };
+
+ static QString curr_version_string;
+
+ bool Version::client_version_compatible()
+ {
+ return svn_ver_compatible(svn_client_version(),&Linkedtag);
+ }
+
+ const QString Version::linked_version()
+ {
+ return QString( SVN_VERSION );
+ }
+
+ const QString Version::running_version()
+ {
+ if (curr_version_string.length()==0) {
+ curr_version_string =
+ QString("%1.%2.%3.%4").arg(svn_client_version()->major).arg(svn_client_version()->minor)
+ .arg(svn_client_version()->patch).arg(svn_client_version()->tag);
+ }
+ return curr_version_string;
+ }
+
+ int Version::version_major()
+ {
+ return svn_client_version()->major;
+ }
+
+ int Version::version_minor()
+ {
+ return svn_client_version()->minor;
+ }
+}
diff --git a/src/svnqt/version_check.hpp b/src/svnqt/version_check.hpp
new file mode 100644
index 0000000..2398645
--- /dev/null
+++ b/src/svnqt/version_check.hpp
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Rajko Albrecht *
+ * ral@alwins-world.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef __VERSION_CHECK_HPP
+#define __VERSION_CHECK_HPP
+
+#include "svnqt/svnqt_defines.hpp"
+
+class QString;
+
+namespace svn {
+ class SVNQT_EXPORT Version {
+
+ public:
+ Version(){}
+ ~Version(){}
+
+ static bool client_version_compatible();
+ static const QString linked_version();
+ static const QString running_version();
+
+ static int version_major();
+ static int version_minor();
+ };
+}
+
+#endif
diff --git a/src/svnqt/wc.cpp b/src/svnqt/wc.cpp
new file mode 100644
index 0000000..bcfe139
--- /dev/null
+++ b/src/svnqt/wc.cpp
@@ -0,0 +1,129 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+// subversion api
+#include "svn_wc.h"
+
+// svncpp
+#include "exception.hpp"
+#include "path.hpp"
+#include "pool.hpp"
+#include "wc.hpp"
+
+namespace svn
+{
+ const char * Wc::ADM_DIR_NAME = SVN_WC_ADM_DIR_NAME;
+
+ bool
+ Wc::checkWc (const QString& dir)
+ {
+ Pool pool;
+ Path path (dir);
+ int wc;
+
+ svn_error_t * error = svn_wc_check_wc (
+ path.path().TOUTF8(),
+ &wc, pool);
+
+ if ((error != NULL) || (wc == 0))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ void
+ Wc::ensureAdm (const QString& dir, const QString& uuid,
+ const QString& url, const Revision & revision) throw (ClientException)
+ {
+ Pool pool;
+ Path dirPath (dir);
+ Path urlPath (url);
+
+ svn_error_t * error =
+ svn_wc_ensure_adm (
+ dirPath.path().TOUTF8(), // path
+ uuid.TOUTF8(), // UUID
+ urlPath.path().TOUTF8(), // url
+ revision.revnum (), // revision
+ pool);
+ if(error != NULL)
+ throw ClientException (error);
+ }
+
+ const svn_wc_entry_t *Wc::getEntry( const QString &path ) throw ( ClientException )
+ {
+ Pool pool;
+ Path itemPath(path);
+ svn_error_t * error = 0;
+ svn_wc_adm_access_t *adm_access;
+ const svn_wc_entry_t *entry;
+ error = svn_wc_adm_probe_open2(&adm_access,0,itemPath.path().TOUTF8(),FALSE,0,pool);
+ if (error!=0) {
+ throw ClientException(error);
+ }
+ error = svn_wc_entry(&entry,itemPath.path().TOUTF8(),adm_access,FALSE,pool);
+ if (error!=0) {
+ throw ClientException(error);
+ }
+ error = svn_wc_adm_close(adm_access);
+ if (error!=0) {
+ throw ClientException(error);
+ }
+ return entry;
+ }
+
+ QString Wc::getUrl(const QString&path) throw (ClientException)
+ {
+ QString result = "";
+ const svn_wc_entry_t *entry;
+ entry = getEntry( path );
+ result = entry?QString::FROMUTF8(entry->url):"";
+
+ return result;
+ }
+
+ QString Wc::getRepos(const QString&path) throw (ClientException)
+ {
+ QString result = "";
+ const svn_wc_entry_t *entry;
+ entry = getEntry( path );
+ result = entry ? QString::FROMUTF8(entry->repos) : QString::fromLatin1("");
+
+ return result;
+ }
+}
+
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */
diff --git a/src/svnqt/wc.hpp b/src/svnqt/wc.hpp
new file mode 100644
index 0000000..b8769f8
--- /dev/null
+++ b/src/svnqt/wc.hpp
@@ -0,0 +1,96 @@
+/*
+ * Port for usage with qt-framework and development for kdesvn
+ * (C) 2005-2007 by Rajko Albrecht
+ * http://kdesvn.alwins-world.de
+ */
+/*
+ * ====================================================================
+ * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library (in the file LGPL.txt); if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St,
+ * Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://rapidsvn.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef _SVNCPP_WC_HPP_
+#define _SVNCPP_WC_HPP_
+
+// Ignore MSVC 7, 2005 & 2008 compiler warning: C++ exception specification
+#if defined (_MSC_VER) && _MSC_VER > 1200 && _MSC_VER <= 1550
+#pragma warning (disable: 4290)
+#endif
+
+// svncpp
+#include "svnqt/exception.hpp"
+#include "svnqt/revision.hpp"
+#include "svnqt/svnqt_defines.hpp"
+
+#include <qstring.h>
+
+namespace svn
+{
+ /**
+ * Class that deals with a working copy
+ */
+ class SVNQT_EXPORT Wc
+ {
+ public:
+ /**
+ * check if Path is a valid working directory
+ *
+ * @param dir path to a directory
+ * @return true=valid working copy
+ */
+ static bool
+ checkWc (const QString& dir);
+
+ /**
+ * ensure that an administrative area exists for @a dir, so that @a dir
+ * is a working copy subdir based on @a url at @a revision.
+ *
+ * @param dir path to a directory
+ * @param uuid
+ * @param url corresponding url
+ * @param revision expected working copy revision
+ */
+ static void
+ ensureAdm (const QString& dir, const QString& uuid,
+ const QString& url, const Revision & revision) throw (ClientException);
+
+ /**
+ * retrieve the url of a given working copy item
+ * @param path the working copy item to check
+ * @return the repository url of @a path
+ */
+ static QString getUrl(const QString&path) throw (ClientException);
+ static QString getRepos(const QString&path) throw (ClientException);
+ static const char * ADM_DIR_NAME;
+
+ private:
+ static const svn_wc_entry_t *getEntry( const QString &path ) throw ( ClientException );
+
+ };
+}
+
+#endif
+/* -----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../rapidsvn-dev.el")
+ * end:
+ */