mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 18:32:51 +00:00
akonadi: import 1.13.0
This commit is contained in:
parent
273587f5ac
commit
438d2bd635
445 changed files with 59528 additions and 0 deletions
6
akonadi/.gitignore
vendored
Normal file
6
akonadi/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Ignore the following files
|
||||||
|
*~
|
||||||
|
*.[oa]
|
||||||
|
*.kdev4
|
||||||
|
.swp.*
|
||||||
|
.*.swp
|
1
akonadi/.kateconfig
Normal file
1
akonadi/.kateconfig
Normal file
|
@ -0,0 +1 @@
|
||||||
|
// kate: space-indent on; indent-width 2; remove-trailing-space on; remove-trailing-space-save on;
|
1
akonadi/.krazy
Normal file
1
akonadi/.krazy
Normal file
|
@ -0,0 +1 @@
|
||||||
|
EXCLUDE i18ncheckarg,syscalls,qclasses,qmethods,crashy,strings,cpp
|
3
akonadi/.reviewboardrc
Normal file
3
akonadi/.reviewboardrc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
REVIEWBOARD_URL = "https://git.reviewboard.kde.org"
|
||||||
|
TARGET_GROUPS = "akonadi"
|
||||||
|
REPOSITORY = "akonadi"
|
88
akonadi/AUTHORS
Normal file
88
akonadi/AUTHORS
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
Maintainer:
|
||||||
|
- Dan Vrátil <dvratil@redhat.com>
|
||||||
|
|
||||||
|
Main Authors:
|
||||||
|
- Volker Krause <vkrause@kde.org>
|
||||||
|
- Till Adam <adam@kde.org>
|
||||||
|
- Tobias Koenig <tokoe@kde.org>
|
||||||
|
- Kevin Krammer <kevin.krammer@gmx.at>
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
- Albert Astals Cid <aacid@kde.org>
|
||||||
|
- Àlex Fiestas <afiestas@kde.org>
|
||||||
|
- Alex Merry <kde@randomguy3.me.uk>
|
||||||
|
- Alexander Neundorf <neundorf@kde.org>
|
||||||
|
- Allen Winter <winter@kde.org>
|
||||||
|
- Andras Mantia <amantia@kde.org>
|
||||||
|
- Andreas Cord-Landwehr <cola@uni-paderborn.de>
|
||||||
|
- Andreas Gungl <a.gungl@gmx.de>
|
||||||
|
- Andreas Hartmetz <ahartmetz@gmail.com>
|
||||||
|
- Andreas Holzammer <andreas.holzammer@kdab.com>
|
||||||
|
- Andreas Pakulat <apaku@gmx.de>
|
||||||
|
- Andre Heinecke <aheinecke@intevation.de>
|
||||||
|
- Aurélien Gâteau <agateau@kde.org>
|
||||||
|
- Bertjan Broeksema <broeksema@kde.org>
|
||||||
|
- Bjoern Ricks <bjoern.ricks@googlemail.com>
|
||||||
|
- Carlo Segato <brandon.ml@gmail.com>
|
||||||
|
- Christian Ehrlicher <Ch.Ehrlicher@gmx.de>
|
||||||
|
- Christian Mollekopf <chrigi_1@fastmail.fm>
|
||||||
|
- Cédric Villemain <cedric@2ndQuadrant.com>
|
||||||
|
- Christian Schaarschmidt <schaarsc@gmx.de>
|
||||||
|
- Christophe Giboudeaux <cgiboudeaux@gmail.com>
|
||||||
|
- Constantin Berzan <exit3219@gmail.com>
|
||||||
|
- Dario Freddi <drf@kde.org>
|
||||||
|
- David Faure <faure@kde.org>
|
||||||
|
- David Jarvie <djarvie@kde.org>
|
||||||
|
- Dirk Mueller <mueller@kde.org>
|
||||||
|
- Frank Osterfeld <frank.osterfeld@kdemail.net>
|
||||||
|
- Grégory Oestreicher <greg@kamago.net>
|
||||||
|
- Gregory Schlomoff <gregory.schlomoff@gmail.com>
|
||||||
|
- Guy Maurel <guy.maurel@kde.org>
|
||||||
|
- Harald Fernengel <harry@kdevelop.org>
|
||||||
|
- Helio Chissini de Castro <helio@kde.org>
|
||||||
|
- Igor Trindade Oliveira <igor_trindade@yahoo.com.br>
|
||||||
|
- Ingo Kloecker <kloecker@kde.org>
|
||||||
|
- Jaime Torres <jtamate@gmail.com>
|
||||||
|
- Jakub Stachowski <qbast@go2.pl>
|
||||||
|
- Jesper Thomschütz <jesperht@yahoo.com>
|
||||||
|
- Jesse Lee Zamora <xtremek2008@aim.com>
|
||||||
|
- Kevin Ottens <ervin@kde.org>
|
||||||
|
- Kitware, Inc., Insight Consortium.
|
||||||
|
- Laurent Montel <montel@kde.org>
|
||||||
|
- Leo Franchi <lfranchi@kde.org>
|
||||||
|
- Loic Marteau <loic.marteau@gmail.com>
|
||||||
|
- Manolo Valdes <nolis71cu@gmail.com>
|
||||||
|
- Marc Mutz <mutz@kde.org>
|
||||||
|
- Marco Martin <notmart@gmail.com>
|
||||||
|
- Matthias Kretz <kretz@kde.org>
|
||||||
|
- Michael Drueing <michael@drueing.de>
|
||||||
|
- Michael Jansen <kde@michael-jansen.biz>
|
||||||
|
- Mike Arthur <mike@mikemcquaid.com>
|
||||||
|
- Milian Wolff <mail@milianw.de>
|
||||||
|
- Mirko Boehm <mirko@kde.org>
|
||||||
|
- Nicolás Alvarez <nicolas.alvarez@gmail.com>
|
||||||
|
- Nicolas Lécureuil <nlecureuil@mandriva.com>
|
||||||
|
- Olivier Trichet <nive@nivalis.org>
|
||||||
|
- Patrick Spendrin <ps_ml@gmx.de>
|
||||||
|
- Pavel Heimlich <tropikhajma@gmail.com>
|
||||||
|
- Pino Toscano <toscano.pino@tiscali.it>
|
||||||
|
- Raphael Kubo da Costa <rakuco@FreeBSD.org>
|
||||||
|
- Rex Dieter <rdieter@math.unl.edu>
|
||||||
|
- Robert Zwerus <arzie@dds.nl>
|
||||||
|
- Rolf Eike Beer <eike-kernel@sf-tec.de>
|
||||||
|
- Romain Pokrzywka <romain@kdab.net>
|
||||||
|
- Sebastian Sauer <mail@dipe.org>
|
||||||
|
- Sebastian Trueg <sebastian@trueg.de>
|
||||||
|
- Sergio Martins <iamsergio@gmail.com>
|
||||||
|
- Shaheed Haque <srhaque@theiet.org>
|
||||||
|
- Stephen Kelly <steveire@gmail.com>
|
||||||
|
- Szymon Stefanek <pragma@kvirc.net>
|
||||||
|
- Thomas Friedrichsmeier <thomas.friedrichsmeier@ruhr-uni-bochum.de>
|
||||||
|
- Thomas McGuire <mcguire@kde.org>
|
||||||
|
- Timo Hummel <timo.hummel@sap.com>
|
||||||
|
- Tom Albers <toma@kde.org>
|
||||||
|
- Torgny Nyblom <kde@nyblom.org>
|
||||||
|
- Vadim Zhukov <persgray@gmail.com>
|
||||||
|
- Will Stephenson <wstephenson@kde.org>
|
||||||
|
- Wolfgang Rohdewald <wolfgang@rohdewald.de>
|
||||||
|
- Yury G. Kudryashov <urkud.urkud@gmail.com>
|
44
akonadi/AkonadiConfig.cmake.in
Normal file
44
akonadi/AkonadiConfig.cmake.in
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# AkonadiConfig.cmake is generated by CMake from akonadi/AkonadiConfig.cmake.in.
|
||||||
|
# Any changed value in this file will be overwritten by CMake.
|
||||||
|
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
# set the akonadi version number
|
||||||
|
set(AKONADI_VERSION_MAJOR @AKONADI_VERSION_MAJOR@)
|
||||||
|
set(AKONADI_VERSION_MINOR @AKONADI_VERSION_MINOR@)
|
||||||
|
set(AKONADI_VERSION_PATCH @AKONADI_VERSION_PATCH@)
|
||||||
|
set(AKONADI_VERSION @AKONADI_VERSION@)
|
||||||
|
set(AKONADI_VERSION_STRING "@AKONADI_VERSION_STRING@")
|
||||||
|
|
||||||
|
# set AKONADI_DEFINITIONS
|
||||||
|
set(AKONADI_USE_STRIGI_SEARCH FALSE) # backward compat, remove eventually
|
||||||
|
set(AKONADI_DEFINITIONS "@AKONADI_DEFINITIONS@")
|
||||||
|
|
||||||
|
# set the directories
|
||||||
|
if(NOT AKONADI_INSTALL_DIR)
|
||||||
|
set(AKONADI_INSTALL_DIR "@CMAKE_INSTALL_PREFIX@")
|
||||||
|
endif(NOT AKONADI_INSTALL_DIR)
|
||||||
|
|
||||||
|
set_and_check(AKONADI_BIN_DIR "@PACKAGE_BIN_INSTALL_DIR@")
|
||||||
|
set_and_check(AKONADI_CONFIG_DIR "@PACKAGE_CONFIG_INSTALL_DIR@")
|
||||||
|
set_and_check(AKONADI_DBUS_INTERFACES_DIR "@PACKAGE_DBUS_INTERFACES_INSTALL_DIR@")
|
||||||
|
set_and_check(AKONADI_DBUS_SERVICES_DIR "@PACKAGE_DBUS_SERVICES_INSTALL_DIR@")
|
||||||
|
set_and_check(AKONADI_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
|
||||||
|
set_and_check(AKONADI_LIB_DIR "@PACKAGE_LIB_INSTALL_DIR@")
|
||||||
|
set_and_check(AKONADI_SHARE_DIR "@PACKAGE_SHARE_INSTALL_PREFIX@")
|
||||||
|
set_and_check(AKONADI_XDG_MIME_INSTALL_DIR "@PACKAGE_XDG_MIME_INSTALL_DIR@")
|
||||||
|
|
||||||
|
# the exports file exports
|
||||||
|
set(AKONADI_TARGET_PREFIX @AKONADI_TARGET_PREFIX@)
|
||||||
|
|
||||||
|
# Load the exported targets.
|
||||||
|
if(NOT TARGET Akonadi__akonadiprotocolinternals)
|
||||||
|
get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||||
|
include("${_currentDir}/AkonadiTargetsWithPrefix.cmake")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
macro(_akonadi_Set_Lib_Vars _prefix _lib)
|
||||||
|
set(AKONADI_${_prefix}_LIBRARIES ${AKONADI_TARGET_PREFIX}${_lib})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
_akonadi_set_lib_vars(COMMON akonadiprotocolinternals)
|
370
akonadi/CMakeLists.txt
Normal file
370
akonadi/CMakeLists.txt
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
project(Akonadi)
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
|
||||||
|
|
||||||
|
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||||
|
set(CMAKE_MODULE_PATH "${Akonadi_SOURCE_DIR}/cmake/modules")
|
||||||
|
|
||||||
|
# Enable CMake's Automoc
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
# Used to report the packages we found
|
||||||
|
include(FeatureSummary)
|
||||||
|
|
||||||
|
############### Build Options ###############
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
include(CTestConfig.cmake)
|
||||||
|
option(AKONADI_BUILD_TESTS "Build the Akonadi unit tests." TRUE)
|
||||||
|
option(AKONADI_BUILD_QSQLITE "Build the Sqlite backend." TRUE)
|
||||||
|
option(INSTALL_QSQLITE_IN_QT_PREFIX "Install the QSQLite plugin in QT_PLUGIN_DIR" FALSE)
|
||||||
|
option(STATIC_LIBRARY "Build Akonadi as a static library." FALSE)
|
||||||
|
option(QT5_BUILD "Build Akonadi using the Qt5 framework" FALSE)
|
||||||
|
option(WITH_SOPRANO "Build with Soprano support. Needed for Nepomuk search integration." FALSE)
|
||||||
|
|
||||||
|
if(NOT DEFINED DATABASE_BACKEND)
|
||||||
|
set(DATABASE_BACKEND "MYSQL" CACHE STRING "The default database backend to use for Akonadi. Can be either MYSQL, POSTGRES or SQLITE")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(AKONADI_BUILD_TESTS)
|
||||||
|
enable_testing()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
############### CMake Macros ###############
|
||||||
|
|
||||||
|
include(InstallSettings)
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
include(CheckIncludeFiles)
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
############### CTest options ###############
|
||||||
|
# Set a timeout value of 1 minute per test
|
||||||
|
set(DART_TESTING_TIMEOUT 60)
|
||||||
|
|
||||||
|
# CTestCustom.cmake has to be in the CTEST_BINARY_DIR.
|
||||||
|
# in the KDE build system, this is the same as CMAKE_BINARY_DIR.
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake COPYONLY)
|
||||||
|
|
||||||
|
############### The Akonadi version (used in AkonadiConfig.cmake) ###############
|
||||||
|
|
||||||
|
set(AKONADI_VERSION_PATCH "0")
|
||||||
|
|
||||||
|
# Raise the minor version if we're building Akonadi using Qt5
|
||||||
|
if(QT5_BUILD)
|
||||||
|
set(AKONADI_VERSION_MAJOR "1")
|
||||||
|
set(AKONADI_VERSION_MINOR "79")
|
||||||
|
set(AKONADI_SOVERSION "2")
|
||||||
|
else ()
|
||||||
|
set(AKONADI_VERSION_MAJOR "1")
|
||||||
|
set(AKONADI_VERSION_MINOR "13")
|
||||||
|
set(AKONADI_SOVERSION "1")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(AKONADI_VERSION "${AKONADI_VERSION_MAJOR}.${AKONADI_VERSION_MINOR}.${AKONADI_VERSION_PATCH}")
|
||||||
|
set(AKONADI_VERSION_STRING "${AKONADI_VERSION}")
|
||||||
|
|
||||||
|
# If Git is installed and a '.git' directory is found,
|
||||||
|
# we append the Git revision to AKONADI_VERSION_STRING
|
||||||
|
if(EXISTS "${Akonadi_SOURCE_DIR}/.git")
|
||||||
|
find_package(Git)
|
||||||
|
if(GIT_FOUND)
|
||||||
|
message(STATUS "Found git: ${GIT_EXECUTABLE}")
|
||||||
|
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
|
||||||
|
WORKING_DIRECTORY ${Akonadi_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE akonadi_git_revision
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
set(AKONADI_VERSION_STRING "${AKONADI_VERSION_STRING} (revision: ${akonadi_git_revision})")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
############### Macros ###############
|
||||||
|
|
||||||
|
macro(SET_DEFAULT_DB_BACKEND)
|
||||||
|
set(_backend ${ARGV0})
|
||||||
|
if("${_backend}" STREQUAL "SQLITE")
|
||||||
|
set(AKONADI_DATABASE_BACKEND QSQLITE3)
|
||||||
|
set(AKONADI_BUILD_QSQLITE TRUE)
|
||||||
|
else()
|
||||||
|
if("${_backend}" STREQUAL "POSTGRES")
|
||||||
|
set(AKONADI_DATABASE_BACKEND QPSQL)
|
||||||
|
else()
|
||||||
|
set(AKONADI_DATABASE_BACKEND QMYSQL)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Using default db backend ${AKONADI_DATABASE_BACKEND}")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
#### DB BACKEND DEFAULT ####
|
||||||
|
set_default_db_backend(${DATABASE_BACKEND})
|
||||||
|
|
||||||
|
|
||||||
|
############### Find what we need ###############
|
||||||
|
|
||||||
|
#### Qt 4 and 5 ####
|
||||||
|
if(QT5_BUILD)
|
||||||
|
find_package(Qt5Core REQUIRED)
|
||||||
|
find_package(Qt5Gui REQUIRED)
|
||||||
|
find_package(Qt5Widgets REQUIRED)
|
||||||
|
find_package(Qt5Sql REQUIRED)
|
||||||
|
find_package(Qt5Network REQUIRED)
|
||||||
|
find_package(Qt5Xml REQUIRED)
|
||||||
|
find_package(Qt5DBus REQUIRED)
|
||||||
|
find_package(Qt5Test REQUIRED)
|
||||||
|
|
||||||
|
include("cmake/modules/ECMQt4To5Porting.cmake")
|
||||||
|
include_directories(${QT_INCLUDES}) # TODO: Port away from this.
|
||||||
|
|
||||||
|
if(CMAKE_VERSION VERSION_LESS 2.8.9)
|
||||||
|
message(FATAL_ERROR "Akonadi Qt 5 build requires at least CMake version 2.8.9")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (Qt5_POSITION_INDEPENDENT_CODE)
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(QT_QTTEST_LIBRARIES Qt5::Test)
|
||||||
|
else()
|
||||||
|
set(QT_USE_IMPORTED_TARGETS TRUE) # Qt 4 only
|
||||||
|
set(QT_MIN_VERSION 4.8.0) # Qt 4 only
|
||||||
|
|
||||||
|
find_package(Qt4 REQUIRED)
|
||||||
|
include(${QT_USE_FILE})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(STATIC_LIBRARY)
|
||||||
|
set(LIBRARY_TYPE STATIC)
|
||||||
|
set(AKONADI_STATIC_LIBS ON)
|
||||||
|
message(STATUS "Building Akonadi as a static library")
|
||||||
|
else()
|
||||||
|
set(LIBRARY_TYPE SHARED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#### Soprano ####
|
||||||
|
if(WITH_SOPRANO)
|
||||||
|
set(SOPRANO_MIN_VERSION 2.7.56)
|
||||||
|
find_package(Soprano)
|
||||||
|
|
||||||
|
set_package_properties(Soprano PROPERTIES
|
||||||
|
URL "http://soprano.sourceforge.net"
|
||||||
|
DESCRIPTION "Storage of semantic data"
|
||||||
|
TYPE REQUIRED
|
||||||
|
PURPOSE "Soprano is needed for the Nepomuk search backend"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#### SMI ####
|
||||||
|
set(SMI_MIN_VERSION "0.20")
|
||||||
|
find_package(SharedMimeInfo ${SMI_MIN_VERSION})
|
||||||
|
set_package_properties(SharedMimeInfo PROPERTIES
|
||||||
|
URL "http://freedesktop.org/wiki/Software/shared-mime-info"
|
||||||
|
DESCRIPTION "File types database and utilities"
|
||||||
|
TYPE REQUIRED
|
||||||
|
)
|
||||||
|
|
||||||
|
#### XSLTProc ####
|
||||||
|
find_program(XSLTPROC_EXECUTABLE xsltproc)
|
||||||
|
if(NOT XSLTPROC_EXECUTABLE)
|
||||||
|
message(FATAL_ERROR "\nThe command line XSLT processor program 'xsltproc' could not be found.\nPlease install xsltproc.\n")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#### Boost ####
|
||||||
|
# In CMake >= 2.8.6, FindBoost.cmake tries to find BoostConfig.cmake which is
|
||||||
|
# not compatible with CMake's FindBoost. Disable this function.
|
||||||
|
set(Boost_NO_BOOST_CMAKE TRUE)
|
||||||
|
|
||||||
|
find_package(Boost COMPONENTS program_options)
|
||||||
|
set_package_properties(Boost PROPERTIES
|
||||||
|
URL "http://www.boost.org"
|
||||||
|
DESCRIPTION "The Boost C++ Libraries"
|
||||||
|
TYPE REQUIRED
|
||||||
|
PURPOSE "Akonadi requires the Boost C++ libraries (program_options)"
|
||||||
|
)
|
||||||
|
|
||||||
|
# should be handled by FindBoost.cmake -> cmake bug #8335
|
||||||
|
if(WIN32 AND NOT Boost_USE_STATIC_LIBS)
|
||||||
|
add_definitions(-DBOOST_DYN_LINK)
|
||||||
|
add_definitions(-DBOOST_PROGRAM_OPTIONS_DYN_LINK)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
#### Sqlite ####
|
||||||
|
# If Sqlite is the default backend, it cannot be optional.
|
||||||
|
if("${DATABASE_BACKEND}" STREQUAL "SQLITE")
|
||||||
|
set(SQLITE_TYPE "REQUIRED")
|
||||||
|
else()
|
||||||
|
set(SQLITE_TYPE "OPTIONAL")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(AKONADI_BUILD_QSQLITE)
|
||||||
|
set(SQLITE_MIN_VERSION 3.6.23)
|
||||||
|
find_package(Sqlite ${SQLITE_MIN_VERSION})
|
||||||
|
set_package_properties(Sqlite PROPERTIES
|
||||||
|
URL "http://www.sqlite.org"
|
||||||
|
DESCRIPTION "The Sqlite database library"
|
||||||
|
TYPE ${SQLITE_TYPE}
|
||||||
|
PURPOSE "Required by the Sqlite backend"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
############### Compilers flags ###############
|
||||||
|
|
||||||
|
option(CMAKE_COMPILE_GCOV "Build with coverage support." FALSE)
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER MATCHES "icc" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
||||||
|
set(_ENABLE_EXCEPTIONS -fexceptions)
|
||||||
|
|
||||||
|
# more aggressive warnings and C++11 support
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long -std=iso9899:1990 -Wundef -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts -Wall -Wextra -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-common")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wnon-virtual-dtor -Wundef -Wcast-align -Wchar-subscripts -Wall -Wextra -Wpointer-arith -Wformat-security -fno-common")
|
||||||
|
|
||||||
|
# debugfull target
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUGFULL "-g3 -fno-inline" CACHE STRING "Flags used by the C++ compiler during debugfull builds." FORCE)
|
||||||
|
set(CMAKE_C_FLAGS_DEBUGFULL "-g3 -fno-inline" CACHE STRING "Flags used by the C compiler during debugfull builds." FORCE)
|
||||||
|
mark_as_advanced(CMAKE_CXX_FLAGS_DEBUGFULL CMAKE_C_FLAGS_DEBUGFULL)
|
||||||
|
|
||||||
|
# Update the documentation string of CMAKE_BUILD_TYPE for ccache & cmake-gui
|
||||||
|
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
|
||||||
|
"Choose the type of build, options are: None debugfull Debug Release RelWithDebInfo MinSizeRel."
|
||||||
|
FORCE)
|
||||||
|
|
||||||
|
# coverage support
|
||||||
|
if(CMAKE_COMPILE_GCOV)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofile_rt" CACHE STRING "Flags used by the linker" FORCE)
|
||||||
|
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -lprofile_rt" CACHE STRING "Flags used by the linker" FORCE)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofile_rt" CACHE STRING "Flags used by the linker" FORCE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
set(_ENABLE_EXCEPTIONS -EHsc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII)
|
||||||
|
add_definitions(-DQT_NO_KEYWORDS)
|
||||||
|
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
|
||||||
|
|
||||||
|
|
||||||
|
############### Configure checks ###############
|
||||||
|
|
||||||
|
set(AKONADI_SYSTEM_LIBS)
|
||||||
|
|
||||||
|
find_package(Backtrace)
|
||||||
|
if(Backtrace_FOUND)
|
||||||
|
include_directories(${Backtrace_INCLUDE_DIRS})
|
||||||
|
set(AKONADI_SYSTEM_LIBS ${AKONADI_SYSTEM_LIBS} ${Backtrace_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||||
|
|
||||||
|
# set the output paths
|
||||||
|
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
if(WIN32)
|
||||||
|
set(LIBRARY_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH})
|
||||||
|
else()
|
||||||
|
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set up RPATH handling, so the libs are found if they are installed to a non-standard location.
|
||||||
|
# By default cmake builds the targets with full RPATH to everything in the build directory,
|
||||||
|
# but then removes the RPATH when installing.
|
||||||
|
# These two options below make it set the RPATH of the installed targets to all
|
||||||
|
# RPATH directories outside the current CMAKE_BINARY_DIR and also the library
|
||||||
|
# install directory, but only if this directory is not a default system library directory. Alex
|
||||||
|
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
|
|
||||||
|
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${LIB_INSTALL_DIR}" _isSystemLibDir)
|
||||||
|
if("${_isSystemLibDir}" STREQUAL "-1")
|
||||||
|
set(CMAKE_INSTALL_RPATH "${LIB_INSTALL_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED AKONADI_BUNDLE_PATH)
|
||||||
|
set(AKONADI_BUNDLE_PATH "/Applications/KDE4")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
message(STATUS "MacOS Bundle Path: ${AKONADI_BUNDLE_PATH}")
|
||||||
|
set(CMAKE_INSTALL_NAME_DIR ${LIB_INSTALL_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
############### Generate files ###############
|
||||||
|
# Used in configure_file() and install(EXPORT). Must be set before setting the AkonadiConfig.cmake vars.
|
||||||
|
set(AKONADI_TARGET_PREFIX Akonadi__)
|
||||||
|
|
||||||
|
if(Soprano_FOUND)
|
||||||
|
set(HAVE_SOPRANO TRUE)
|
||||||
|
endif()
|
||||||
|
configure_file(akonadi-prefix.h.cmake ${Akonadi_BINARY_DIR}/akonadi-prefix.h)
|
||||||
|
configure_file(config-akonadi.h.cmake ${Akonadi_BINARY_DIR}/config-akonadi.h)
|
||||||
|
|
||||||
|
# This command will replace the installation dirs with absolute paths in AkonadiConfig.cmake
|
||||||
|
configure_package_config_file(AkonadiConfig.cmake.in ${Akonadi_BINARY_DIR}/AkonadiConfig.cmake
|
||||||
|
INSTALL_DESTINATION ${LIB_INSTALL_DIR}/cmake/Akonadi
|
||||||
|
PATH_VARS BIN_INSTALL_DIR INCLUDE_INSTALL_DIR
|
||||||
|
LIB_INSTALL_DIR CONFIG_INSTALL_DIR
|
||||||
|
DBUS_INTERFACES_INSTALL_DIR DBUS_SERVICES_INSTALL_DIR
|
||||||
|
SHARE_INSTALL_PREFIX XDG_MIME_INSTALL_DIR
|
||||||
|
)
|
||||||
|
|
||||||
|
# this file is used by to check if the installed version can be used.
|
||||||
|
write_basic_package_version_file(${Akonadi_BINARY_DIR}/AkonadiConfigVersion.cmake
|
||||||
|
VERSION ${AKONADI_VERSION}
|
||||||
|
COMPATIBILITY SameMajorVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
configure_file(${Akonadi_SOURCE_DIR}/akonadi.pc.cmake ${Akonadi_BINARY_DIR}/akonadi.pc @ONLY)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
############### build targets ###############
|
||||||
|
|
||||||
|
include_directories(${Akonadi_SOURCE_DIR} ${Akonadi_BINARY_DIR} ${QT_INCLUDES} ${Boost_INCLUDE_DIR})
|
||||||
|
|
||||||
|
add_subdirectory(interfaces)
|
||||||
|
add_subdirectory(libs)
|
||||||
|
set(AKONADI_PROTOCOLINTERNALS_LIBS ${akonadiprotocolinternals_LIB_DEPENDS} akonadiprotocolinternals)
|
||||||
|
|
||||||
|
add_subdirectory(shared)
|
||||||
|
add_subdirectory(agentserver)
|
||||||
|
add_subdirectory(server)
|
||||||
|
|
||||||
|
add_subdirectory(rds)
|
||||||
|
if(NOT WIN32)
|
||||||
|
add_subdirectory(asapcat)
|
||||||
|
endif()
|
||||||
|
if (NOT QT5_BUILD)
|
||||||
|
if(SQLITE_FOUND)
|
||||||
|
option(SQLITE_LINK_STATIC "link libsqlite3 statically" FALSE)
|
||||||
|
add_subdirectory(qsqlite)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
############### install stuff ###############
|
||||||
|
|
||||||
|
install(FILES ${Akonadi_BINARY_DIR}/AkonadiConfigVersion.cmake
|
||||||
|
${Akonadi_BINARY_DIR}/AkonadiConfig.cmake
|
||||||
|
DESTINATION ${LIB_INSTALL_DIR}/cmake/Akonadi)
|
||||||
|
|
||||||
|
install(FILES akonadi-mime.xml DESTINATION ${XDG_MIME_INSTALL_DIR})
|
||||||
|
update_xdg_mimetypes(${XDG_MIME_INSTALL_DIR})
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
install(FILES ${Akonadi_BINARY_DIR}/akonadi.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
feature_summary(WHAT ALL
|
||||||
|
INCLUDE_QUIET_PACKAGES
|
||||||
|
FATAL_ON_MISSING_REQUIRED_PACKAGES
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install the file with the exported targets
|
||||||
|
install(EXPORT akonadiLibraryTargets
|
||||||
|
NAMESPACE ${AKONADI_TARGET_PREFIX}
|
||||||
|
DESTINATION ${LIB_INSTALL_DIR}/cmake/Akonadi
|
||||||
|
FILE AkonadiTargetsWithPrefix.cmake)
|
13
akonadi/CTestConfig.cmake
Normal file
13
akonadi/CTestConfig.cmake
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
## This file should be placed in the root directory of your project.
|
||||||
|
## Then modify the CMakeLists.txt file in the root directory of your
|
||||||
|
## project to incorporate the testing dashboard.
|
||||||
|
## # The following are required to uses Dart and the Cdash dashboard
|
||||||
|
## ENABLE_TESTING()
|
||||||
|
## INCLUDE(CTest)
|
||||||
|
set(CTEST_PROJECT_NAME "akonadi")
|
||||||
|
set(CTEST_NIGHTLY_START_TIME "00:00:00 UTC")
|
||||||
|
|
||||||
|
set(CTEST_DROP_METHOD "http")
|
||||||
|
set(CTEST_DROP_SITE "my.cdash.org")
|
||||||
|
set(CTEST_DROP_LOCATION "/submit.php?project=akonadi")
|
||||||
|
set(CTEST_DROP_SITE_CDASH TRUE)
|
22
akonadi/CTestCustom.cmake
Normal file
22
akonadi/CTestCustom.cmake
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# This file contains all the specific settings that will be used
|
||||||
|
# when running 'make Experimental'
|
||||||
|
|
||||||
|
# Change the maximum warnings that will be displayed
|
||||||
|
# on the report page (default 50)
|
||||||
|
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS 1000)
|
||||||
|
|
||||||
|
# Errors that will be ignored
|
||||||
|
set(CTEST_CUSTOM_ERROR_EXCEPTION
|
||||||
|
${CTEST_CUSTOM_ERROR_EXCEPTION}
|
||||||
|
"ICECC"
|
||||||
|
"Segmentation fault"
|
||||||
|
"GConf Error"
|
||||||
|
"Client failed to connect to the D-BUS daemon"
|
||||||
|
"Failed to connect to socket"
|
||||||
|
"qlist.h.*increases required alignment of target type"
|
||||||
|
"qmap.h.*increases required alignment of target type"
|
||||||
|
"qhash.h.*increases required alignment of target type"
|
||||||
|
)
|
||||||
|
|
||||||
|
# No coverage for these files (auto-generated, unit tests, etc)
|
||||||
|
set(CTEST_CUSTOM_COVERAGE_EXCLUDE ".moc$" "moc_" "ui_" "/libs/tests" "/server/tests" "qrc_" "adaptor.h$" "adaptor.cpp$" "/server/[^/]+interface\\.")
|
8
akonadi/CodingStyle.txt
Normal file
8
akonadi/CodingStyle.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
The all directory "akonadi" is tested for all rules of the coding style.
|
||||||
|
But of the qsqlite subdirectory which contains a .no_coding_style file.
|
||||||
|
|
||||||
|
The rules and all the scripts are free for download and comments at:
|
||||||
|
http://techbase.kde.org/Policies/Kdepim_Coding_Style
|
||||||
|
|
||||||
|
Feel free to communicate any comments or/and bugs:
|
||||||
|
guy dot maurel at kde dot org
|
64
akonadi/INSTALL
Normal file
64
akonadi/INSTALL
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
Akonadi's build system uses cmake.
|
||||||
|
|
||||||
|
So to compile Akonadi first create a build dir
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
then run cmake:
|
||||||
|
|
||||||
|
cmake ..
|
||||||
|
|
||||||
|
(a typical cmake option that is often used is: -DCMAKE_INSTALL_PREFIX=<prefix>)
|
||||||
|
|
||||||
|
cmake then presents a configuration summary. At this point you may
|
||||||
|
want to install missing dependancies (if you do, remove the CMakeCache.txt)
|
||||||
|
and run cmake again.
|
||||||
|
|
||||||
|
Finally build Akonadi:
|
||||||
|
|
||||||
|
make
|
||||||
|
|
||||||
|
And install it (in most cases root privileges are required):
|
||||||
|
|
||||||
|
make install
|
||||||
|
|
||||||
|
That's all :)
|
||||||
|
|
||||||
|
=== Build Options ===
|
||||||
|
|
||||||
|
The following options are available when running CMake:
|
||||||
|
|
||||||
|
* AKONADI_BUILD_TESTS (Default: TRUE): Build the Akonadi unit tests
|
||||||
|
* AKONADI_BUILD_QSQLITE (Default: TRUE): Build the SQLite backend
|
||||||
|
* INSTALL_QSQLITE_IN_QT_PREFIX (Default: FALSE): Useful for distributions.
|
||||||
|
Once enabled, the qsqlite3 backend will be installed in ${QT_PLUGINS_DIR}/sqldrivers
|
||||||
|
* STATIC_LIBRARY (Default: FALSE): Build the Akonadi server libraries statically. Only useful for certain cases (eg: WINCE builds).
|
||||||
|
* DATABASE_BACKEND (Default: MYSQL, available: MYSQL, POSTGRES, SQLITE): Define which database driver to use by default.
|
||||||
|
MYSQL is preferred, SQLITE should be avoided.
|
||||||
|
* QT5_BUILD (Default: FALSE): Build against Qt5 instead of Qt4.
|
||||||
|
* WITH_SOPRANO (Default: TRUE): Don't build with Soprano/Nepomuk support
|
||||||
|
|
||||||
|
=== Build Requirements ===
|
||||||
|
|
||||||
|
Required:
|
||||||
|
|
||||||
|
* Boost (http://www.boost.org)
|
||||||
|
* CMake (http://www.cmake.org) >= 2.8.8
|
||||||
|
* Qt4 >= 4.6.0 (http://qt.nokia.com/downloads)
|
||||||
|
* Shared-mime-info >= 0.20 (http://freedesktop.org/wiki/Software/shared-mime-info)
|
||||||
|
* Xsltproc (http://xmlsoft.org/XSLT/downloads.html)
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
* Mysqld (http://www.mysql.com) - Optional at build time. You can pass -DMYSQLD_EXECUTABLE=/path/to/mysqld when running CMake instead
|
||||||
|
* SQlite >= 3.6.23 (http://www.sqlite.org) - Needed if you want to build the Sqlite backend
|
||||||
|
* Postgresql (http://www.postgres.org) - Optional at build time. You can pass -DPOSTGRES_PATH=/path/to/pg_ctl when running CMake instead
|
||||||
|
* Soprano (http://soprano.sourceforge.net)
|
||||||
|
|
||||||
|
=== Runtime Requirements ===
|
||||||
|
|
||||||
|
* SQlite if you plan to use the SQLite backend (NOT RECOMMENDED for desktop)
|
||||||
|
* MySQL server >= 5.1.3 (or compatible replacements such as MariaDB) if you plan to use the Mysql backend
|
||||||
|
* a Postgresql server if you plan to use the Postgres backend
|
||||||
|
|
36
akonadi/Info.plist.template
Normal file
36
akonadi/Info.plist.template
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>English</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleGetInfoString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleLongVersionString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||||
|
<key>CSResourcesFileMapped</key>
|
||||||
|
<true/>
|
||||||
|
<key>LSRequiresCarbon</key>
|
||||||
|
<true/>
|
||||||
|
<key>LSUIElement</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
340
akonadi/Mainpage.dox
Normal file
340
akonadi/Mainpage.dox
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
/**
|
||||||
|
\mainpage %Akonadi Server
|
||||||
|
|
||||||
|
<p><b>
|
||||||
|
Overview |
|
||||||
|
\ref akonadi_server_definitions |
|
||||||
|
\ref akonadi_server_srclayout
|
||||||
|
</b></p>
|
||||||
|
|
||||||
|
Akonadi aims to be an extensible cross-desktop storage service for PIM data
|
||||||
|
and meta data providing concurrent read, write, and query access.
|
||||||
|
It provides unique desktop-wide object identification and retrieval.
|
||||||
|
|
||||||
|
This is the API documentation for the Akonadi server. If you are using Akonadi
|
||||||
|
from within KDE, you almost certainly want the
|
||||||
|
<a href="http://api.kde.org/4.x-api/kdepimlibs-apidocs/akonadi/html/index.html">KDE client library documentation</a>.
|
||||||
|
This API reference is more useful to people implementing client libraries or
|
||||||
|
working on the Akonadi server itself.
|
||||||
|
|
||||||
|
For additional information, see the <a href="http://community.kde.org/KDE_PIM/Akonadi">Akonadi website</a>.
|
||||||
|
|
||||||
|
\section akonadi_server_architecture Architecture
|
||||||
|
|
||||||
|
<img src="http://community.kde.org/images.community/8/8e/Akonadi_Architecture.png"/>
|
||||||
|
|
||||||
|
The Akonadi framework uses a client/server architecture. The Akonadi server has the following primary tasks:
|
||||||
|
\li Abstract access to data from arbitrary sources, using toolkit-agnostic protocols and data formats
|
||||||
|
\li Provide a data cache shared among several clients
|
||||||
|
\li Provide change notifications and conflict detection
|
||||||
|
\li Support offline change recording and change replay for remote data
|
||||||
|
|
||||||
|
\subsection akonadi_server_design_principles Design Principles
|
||||||
|
|
||||||
|
The Akonadi architecture is based on the following four design principles:
|
||||||
|
|
||||||
|
\li <em>Functionality is spread over different processes.</em><br>
|
||||||
|
This separation has the big advantage that if one process crashes because of
|
||||||
|
a programming error it doesn't affect the other components. That results in
|
||||||
|
robustness of the whole system. A disadvantage might be that there is an additional
|
||||||
|
overhead due to inter-process communication.
|
||||||
|
\li <em>Communication protocol is split into data and control channel.</em><br>
|
||||||
|
When doing communication between processes you have to differentiate between the type of data
|
||||||
|
that is being transferred. For a large amount of data a high-performance
|
||||||
|
protocol should be used and for control data a low-latency protocol.
|
||||||
|
Matching both requirements in one protocol is mostly impossible and hard to
|
||||||
|
achieve with currently available software.
|
||||||
|
\li <em>Separate logic from storage.</em><br>
|
||||||
|
By separating the logic from the storage, the storage can be used to store data
|
||||||
|
of any type. In this case, the storage is a kind of service, which is available for
|
||||||
|
other components of the system. The logic is located in separated components and so
|
||||||
|
3rd-party developers can extend the system by providing their own components.
|
||||||
|
\li <em>Keep communication asynchronous.</em><br>
|
||||||
|
To allow a non-blocking GUI, all the communication with the back-end and within the
|
||||||
|
back-end itself must be asynchronous. You can easily provide a synchronous convenience
|
||||||
|
for the application developer; the back-end, however, must communicate asynchronously.
|
||||||
|
|
||||||
|
\subsection akonadi_server_components Components
|
||||||
|
|
||||||
|
The Akonadi server itself consists of a number of components:
|
||||||
|
\li The Akonadi control process (\c akonadi_control). It is responsible for managing all other server components
|
||||||
|
and Akonadi agents.
|
||||||
|
\li The Akonadi server process (\c akonadiserver). The actual data access and caching server.
|
||||||
|
\li The Akonadi agent server (\c akonadi_agent_server). Allows running of multiple Akonadi agents in one process.
|
||||||
|
\li The Akonadi agent launcher (\c akonadi_agent_launcher). A helper process for running Akonadi agents.
|
||||||
|
\li The Akonadi control tool (\c akonadictl). A tool to start/stop/restart the Akonadi server system and query its status.
|
||||||
|
This is the only program of these listed here you should ever run manually.
|
||||||
|
\li The Akonadi protocol library (\c libakonadiprotocolinternals), Contains protocol definitions and protocol parsing methods
|
||||||
|
useful for client implementations.
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_components_server The Akonadi server process
|
||||||
|
|
||||||
|
The %Akonadi server process (\c akonadiserver) has the following tasks:
|
||||||
|
\li Provide a transaction-safe data store.
|
||||||
|
\li Provide operations to add/modify/delete items and collections in the local store, implementing the server side of the ASAP protocol.
|
||||||
|
\li Cache management of cached remote contents.
|
||||||
|
\li Manage virtual collections representing search results.
|
||||||
|
\li Provide change notifications for all known Akonadi objects over D-Bus.
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_components_control The Akonadi server control process
|
||||||
|
|
||||||
|
The %Akondi control process (\c akonadi_control) has the following tasks:
|
||||||
|
\li Manage and monitor the other server processes.
|
||||||
|
\li Lifecycle management of agent instances using the various supported agent launch methods.
|
||||||
|
\li Monitor agent instances and provide crash recovery.
|
||||||
|
\li Provide D-Bus API to manage agents.
|
||||||
|
\li Provide change notifications on agent types and agent instances.
|
||||||
|
|
||||||
|
|
||||||
|
\section akonadi_server_objects Objects and Data Types
|
||||||
|
|
||||||
|
The %Akonadi server operates on two basic object types, called items and collections. They are comparable to files and directories
|
||||||
|
and are described in more detail in this section.
|
||||||
|
|
||||||
|
\subsection akonadi_server_objects_items Akonadi Items
|
||||||
|
|
||||||
|
An item is a generic container for whatever you want to store in Akonadi (eg. mails,
|
||||||
|
events, contacts, etc.). An item consists of some generic information (such as identifier,
|
||||||
|
mimetype, change date, flags, etc.) and a set of data fields, the item parts. Items
|
||||||
|
are independent of the type of stored data, the semantics of the actual content is only
|
||||||
|
known on the client side.
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_objects_items_parts Item Parts
|
||||||
|
|
||||||
|
%Akonadi items can have one or more parts, e.g. an email message consists of the
|
||||||
|
envelope, the body and possible one or more attachments. Item parts are identified
|
||||||
|
by an identifier string. There are a few special pre-defined part identifiers (ALL,
|
||||||
|
ENVELOPE, etc.), but in general the part identifiers are defined by the type specific
|
||||||
|
extensions (ie. resource, serializer plugin, type specific client library).
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_objects_items_attributes Item Tags
|
||||||
|
|
||||||
|
%Tags are self-contained entities stored in separate database table. A tag is a
|
||||||
|
relation between multiple items. Tags can have different types (PLAIN, ...) and applications
|
||||||
|
can define their own type to describe application-specific relations. Tags can also have
|
||||||
|
attributes to store additional metadata about the relation the tag describes.
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_objects_items_serializer Payload Data Serialization
|
||||||
|
|
||||||
|
Item payload data is typically serialized in a standard format to ensure interoperability between different
|
||||||
|
client library implementations. However, the %Akonadi server does not enforce any format,
|
||||||
|
payload data is handled as an opaque binary blob.
|
||||||
|
|
||||||
|
\subsection akonadi_server_objects_collections Collections
|
||||||
|
|
||||||
|
Collections are sets of items. Every item is stored in exactly one
|
||||||
|
collection, this is sometimes also referred to as the "physical" storage location of the item.
|
||||||
|
An item might also be visible in several other collections - so called "virtual collections" -
|
||||||
|
which are defined as the result set of a search query.
|
||||||
|
|
||||||
|
Collections are organized hierarchically, i.e. a collection can have child
|
||||||
|
collections, thus defining a collection tree.
|
||||||
|
|
||||||
|
Collections are uniquely identified by their identifier in
|
||||||
|
contrast to their path, which is more robust with regard to renaming and moving.
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_objects_collections_akonadi Collection Properties
|
||||||
|
|
||||||
|
Every collection has a set of supported content types.
|
||||||
|
These are the mimetypes of items the collection can contain.
|
||||||
|
Example: A collection of a folder-less iCal file resource would only support
|
||||||
|
"text/calendar" items, a folder on an IMAP server "message/rfc822" but also
|
||||||
|
"inode/directory" if it can contain sub-folders.
|
||||||
|
|
||||||
|
There is a cache policy associated with every collection which defines how much
|
||||||
|
of its content should be kept in the local cache and for how long.
|
||||||
|
|
||||||
|
Additionally, collections can contain an arbitrary set of attributes to represent
|
||||||
|
various other collection properties such as ACLs, quotas or backend-specific data
|
||||||
|
used for incremental synchronization. Evaluation of such attributes is the responsibility
|
||||||
|
of client implementations, the %Akonadi server does not interpret properties
|
||||||
|
other than content types and cache policies.
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_objects_collections_tree Collection Tree
|
||||||
|
|
||||||
|
There is a single collection tree in Akonadi, consisting of several parts:
|
||||||
|
|
||||||
|
- A root node, id 0
|
||||||
|
- One or more top-level collections for each resource. Think of these as mount-points
|
||||||
|
for the resource. The resources must put their items and sub-collections into their
|
||||||
|
corresponding top-level collection.
|
||||||
|
- Resource-dependent sub-collections below the resource top-level collections.
|
||||||
|
If the resource represents data that is organized in folders (e.g. an IMAP
|
||||||
|
resource), it can create additional collections below its top-level
|
||||||
|
collection. These have to be synched with the corresponding backend by the
|
||||||
|
resource.
|
||||||
|
Resources which represent folder-less data (e.g. an iCal file) don't need
|
||||||
|
any sub-collections and put their items directly into the top-level collection.
|
||||||
|
- A top-level collection containing virtual collections.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
\verbatim
|
||||||
|
+-+ resource-folder1
|
||||||
|
| +- sub-folder1
|
||||||
|
| +- sub-folder2
|
||||||
|
| ...
|
||||||
|
+-+ resource-folder2
|
||||||
|
| ...
|
||||||
|
|
|
||||||
|
+-+ Searches
|
||||||
|
+- search-folder1
|
||||||
|
+- search-folder2
|
||||||
|
...
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
|
||||||
|
\subsection akonadi_server_objects_identification Object Identification
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_objects_identification_uid Unique Identifier
|
||||||
|
|
||||||
|
Every object stored in %Akonadi (collections and items) has a unique
|
||||||
|
identifier in the form of an integer value. This identifier cannot be changed in
|
||||||
|
any way and will stay the same, regardless of any modifications to the referred
|
||||||
|
object. A unique identifier will never be used twice and is globally unique,
|
||||||
|
therefore it is possible to retrieve an item without knowing the collection it belongs to.
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_objects_identification_rid Remote Identifier
|
||||||
|
|
||||||
|
Every object can also have an optional so-called remote identifier. This is an
|
||||||
|
identifier used by the corresponding resource to identify the object on its
|
||||||
|
backend (e.g., a groupware server).
|
||||||
|
|
||||||
|
The remote identifier can be changed by the owning resource agent only.
|
||||||
|
|
||||||
|
Special case applies for Tags, where each tag can have multiple remote IDs. This fact is
|
||||||
|
however opaque to resources as each resource is shown only the remote ID that it had
|
||||||
|
provided when inserting the tag into Akonadi.
|
||||||
|
|
||||||
|
\subsubsection akonadi_server_objects_identification_gid Global Identifier
|
||||||
|
|
||||||
|
Every item can has also so called GID, an identifier specific to the content (payload)
|
||||||
|
of the item. The GID is extracted from the payload by client serializer when storing the
|
||||||
|
item in Akonadi. For example, contacts have vCard "UID" field as their GID, emails can
|
||||||
|
use value of "Message-Id" header.
|
||||||
|
|
||||||
|
\section akonadi_server_protocols Communication Protocols
|
||||||
|
|
||||||
|
For communication within the Akonadi server infrastructure and for communication with Akonadi clients, two communication technologies are used:
|
||||||
|
\li \em D-Bus Used for management tasks and change notifications.
|
||||||
|
\li \em ASAP (Akonadi Server Access Protocol), used for high-throughput data transfer. ASAP is based on the well-known IMAP protocol (RFC 3501)
|
||||||
|
which has been proven it's ability to handle large quantities of data in practice already.
|
||||||
|
|
||||||
|
\todo add protocol documentation
|
||||||
|
|
||||||
|
|
||||||
|
\section akonadi_server_interaction Interacting with Akonadi
|
||||||
|
|
||||||
|
There are various possibilities to interact with %Akonadi.
|
||||||
|
|
||||||
|
\section akonadi_server_interaction_client_libraray Akonadi Client Libraries
|
||||||
|
|
||||||
|
Accessing the %Akonadi server using the ASAP and D-Bus interfaces directly is cumbersome.
|
||||||
|
Therefore you'd usually use a client library implementing the low-level protocol handling
|
||||||
|
and providing convenient high-level APIs for %Akonadi operations.
|
||||||
|
|
||||||
|
Currently, the most complete implementation is the
|
||||||
|
<a href="http://api.kde.org/4.x-api/kdepimlibs-apidocs/akonadi/html/index.html">KDE %Akonadi client library</a>.
|
||||||
|
|
||||||
|
<!--
|
||||||
|
// Afaik there are no "other ones"? -- dvratil
|
||||||
|
\todo add links to the other ones
|
||||||
|
//-->
|
||||||
|
|
||||||
|
\subsection akonadi_server_interaction_agents Akonadi Agents
|
||||||
|
|
||||||
|
%Akonadi agents are processes which are controlled by the Akonadi server itself. Agents typically
|
||||||
|
operate autonomously (ie. without much user interaction) on the objects handled by Akonadi, mostly
|
||||||
|
by reacting to change notifications sent by the %Akonadi server.
|
||||||
|
|
||||||
|
Agents can implement specialized interfaces to provide additional functionality.
|
||||||
|
The most important ones are the so-called resource agents.
|
||||||
|
|
||||||
|
Resource agents are connectors that provide access to data from an external source, and replay local changes
|
||||||
|
back to their corresponding backend.
|
||||||
|
|
||||||
|
|
||||||
|
\section akonadi_server_implementation Implementation Details
|
||||||
|
|
||||||
|
\subsection akonadi_server_implementation_storage Data and Metadata Storage
|
||||||
|
|
||||||
|
The Akonadi server uses two mechanisms for data storage:
|
||||||
|
\li A SQL databases for metadata and small payload data
|
||||||
|
\li Plain files for large payload data
|
||||||
|
|
||||||
|
More details on the SQL database layout can be found here: \ref akonadi_server_database.
|
||||||
|
|
||||||
|
The following SQL databases are supported by the Akonadi server:
|
||||||
|
\li \em MySQL using the default QtSQL driver shipped with Qt
|
||||||
|
\li \em Sqlite using the improved QtSQL driver shipped with the Akonadi server
|
||||||
|
\li \em PostgreSQL using the default QtSQL driver shipped with Qt
|
||||||
|
|
||||||
|
For details on how to configure the various backends, see Akonadi::DataStore.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\page akonadi_server_definitions Type Definitions
|
||||||
|
|
||||||
|
<p><b>
|
||||||
|
\ref index "Overview" |
|
||||||
|
\ref Type Definitions |
|
||||||
|
\ref akonadi_server_srclayout
|
||||||
|
</b></p>
|
||||||
|
|
||||||
|
To let all components play together nicely, we have to use some common encoding
|
||||||
|
definitions.
|
||||||
|
|
||||||
|
\li <em>Collection names</em><br>
|
||||||
|
Collection names and paths are Unicode strings (QString) to allow custom names by the user.
|
||||||
|
\li <em>Data references</em><br>
|
||||||
|
The persistent identifier is an unsigned integer and the external URL is
|
||||||
|
a Unicode string (QString).
|
||||||
|
\li <em>Transferred data over ASAP</em><br/>
|
||||||
|
The data transferred over ASAP are byte arrays (QByteArray). If Unicode strings are
|
||||||
|
transferred over ASAP, UTF-8 encoding is applied.
|
||||||
|
\li <em>Error and status messages</em><br>
|
||||||
|
Error and status messages are visible to the user, so they have to be
|
||||||
|
Unicode strings (QString).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\page akonadi_server_srclayout Source Code Layout
|
||||||
|
|
||||||
|
<p><b>
|
||||||
|
\ref index "Overview" |
|
||||||
|
\ref akonadi_server_definitions |
|
||||||
|
\ref Source Code Layout
|
||||||
|
</b></p>
|
||||||
|
|
||||||
|
The code of the storage and control components is located in the \c server sub-directory.
|
||||||
|
The different parts are laid out as follows:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li> \e control <br>
|
||||||
|
Contains the source code of the \ref akonadi_design_control "control" component.
|
||||||
|
<li> \e interfaces <br>
|
||||||
|
Contains the D-Bus interface descriptions of the Akonadi components
|
||||||
|
<li> \e src <br>
|
||||||
|
Contains the source code of the \ref akonadi_design_storage "storage" component.
|
||||||
|
<li> \e src/handler <br>
|
||||||
|
Contains the source code for the handlers of the single ASAP commands.
|
||||||
|
See <a href="group__akonadi__server__handler.html">command handlers module</a>
|
||||||
|
<li> \e src/storage <br>
|
||||||
|
Contains the source code for accessing the storage back-end.<br>
|
||||||
|
<ul>
|
||||||
|
<li> entity.{h,cpp} <br>
|
||||||
|
The files contain classes which reflect records in the tables of the database.
|
||||||
|
They are generated by XSL transformation from akonadidb.xml and entities.xsl
|
||||||
|
<li> datastore.{h,cpp} <br>
|
||||||
|
The files contain a class which provides the access to the underlaying database tables.
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DOXYGEN_EXCLUDE = sqlplugin server/control server/akonadictl server/tests
|
||||||
|
// DOXYGEN_PROJECTNAME=Akonadi
|
||||||
|
// DOXYGEN_PROJECTVERSION=1.10.43
|
||||||
|
|
||||||
|
// vim:ts=4:sw=4:expandtab:filetype=doxygen
|
529
akonadi/NEWS
Normal file
529
akonadi/NEWS
Normal file
|
@ -0,0 +1,529 @@
|
||||||
|
1.13.0 10-August-2014
|
||||||
|
----------------------------------------------
|
||||||
|
- Fixed virtual collections statistics
|
||||||
|
- Fixed tag RID fetch
|
||||||
|
- Fixed HRID-based fetches
|
||||||
|
- Fixed race condition in StorageDebugger
|
||||||
|
- Use FindBacktrace.cmake from CMake 3.0 instead of our own detection
|
||||||
|
|
||||||
|
1.12.90 07-July-2014
|
||||||
|
----------------------------------------------
|
||||||
|
- MERGE command for faster synchronization
|
||||||
|
- Optimizations in various commands handlers
|
||||||
|
- SELECT command is obsolete now
|
||||||
|
- Performance and concurrency improvements in QSQLITE3 driver
|
||||||
|
- Introduced Collection sync preferences as an improvement over the IMAP-based subscription model
|
||||||
|
- Disable filesystem copy-on-write for DB files when running on Btrfs
|
||||||
|
- Introduced direct streaming of external parts
|
||||||
|
- Fixed SearchManager DBus interface not being registered to DBus
|
||||||
|
- Fixed handling of tags in AK-APPEND and MERGE commands
|
||||||
|
- Various fixes in virtual collections handling
|
||||||
|
|
||||||
|
1.12.1 07-April-2014
|
||||||
|
----------------------------------------------
|
||||||
|
- Fixed deadlock in SearchManager
|
||||||
|
- Fixed notification emission when appending items
|
||||||
|
- Fixed ItemRetriever ignoring changeSince argument
|
||||||
|
- Fixed X-AKAPPEND command response
|
||||||
|
- Fixed RID-based FETCH
|
||||||
|
- Fixed data loss in case of long-lasting copy or move operations
|
||||||
|
|
||||||
|
1.12.0 25-March-2014
|
||||||
|
----------------------------------------------
|
||||||
|
- Improved 'akonadictl status' command output
|
||||||
|
- Fixed indexing of items in collections with short cache expiration
|
||||||
|
- Fixed building Akonadi in subdirectory
|
||||||
|
- Fixed deadlock in SearchManager
|
||||||
|
- Fixed runtime warnings
|
||||||
|
|
||||||
|
1.11.90 19-March-2014
|
||||||
|
----------------------------------------------
|
||||||
|
- Fixed collection scheduling
|
||||||
|
- Fixed indexing of expired items from local resources
|
||||||
|
- Fixed database schema update with PostgreSQL
|
||||||
|
- Fixes in searching and search updates
|
||||||
|
|
||||||
|
1.11.80 28-February-2014
|
||||||
|
----------------------------------------------
|
||||||
|
- Server-search support
|
||||||
|
- Search plugins support
|
||||||
|
- Tags support
|
||||||
|
- Fixes and improvements in search
|
||||||
|
- Fixes in protocol parser
|
||||||
|
- Fixed inter-resource moves
|
||||||
|
- Fixed .desktop files parsing
|
||||||
|
- Optimized collections tasks scheduling
|
||||||
|
- Optimized flags handling
|
||||||
|
- Optimized appending new items via AK-APPEND
|
||||||
|
- Handle database transactions deadlocks and timeouts
|
||||||
|
- Improved PostgreSQL support
|
||||||
|
- Soprano is now an optional dependency
|
||||||
|
- Removed MySQL Embedded support
|
||||||
|
|
||||||
|
1.11.0 28-November-2013
|
||||||
|
----------------------------------------------
|
||||||
|
- fix joined UPDATE queries failing with SQLite
|
||||||
|
|
||||||
|
1.10.80 05-November-2013
|
||||||
|
----------------------------------------------
|
||||||
|
- Servser-side notification filtering
|
||||||
|
- GID support
|
||||||
|
- Export custom agent properties to clients
|
||||||
|
- Faster Akonadi shutdown
|
||||||
|
- Improved and faster database schema check on start
|
||||||
|
- Enabled C++11 support
|
||||||
|
- Optimize some SQL queries
|
||||||
|
- Store only relative paths to external payload files in database
|
||||||
|
|
||||||
|
1.10.3 04-October-2013
|
||||||
|
----------------------------------------------
|
||||||
|
- Fix support for latest PostgreSQL
|
||||||
|
- Check MySQL version at runtime, require at least 5.1
|
||||||
|
- Fix crash when destroying DataStore with backends other than MySQL
|
||||||
|
- Fix problem with too long socket paths
|
||||||
|
- Send dummy queries to MySQL to keep the connection alive
|
||||||
|
- Fix crash when no flags are changed
|
||||||
|
|
||||||
|
1.10.2 23-July-2013
|
||||||
|
----------------------------------------------
|
||||||
|
- Fix PostgreSQL support (once more)
|
||||||
|
|
||||||
|
1.10.1 22-July-2013
|
||||||
|
----------------------------------------------
|
||||||
|
- Fix PostgreSQL support
|
||||||
|
- Optimize appending flags to items
|
||||||
|
- Introduce CHANGEDSINCE parameter to FETCH command
|
||||||
|
|
||||||
|
1.10.0 09-July-2013
|
||||||
|
----------------------------------------------
|
||||||
|
- Memory optimizations
|
||||||
|
- Fix a runtime error on Windows
|
||||||
|
|
||||||
|
1.9.80 10-June-2013
|
||||||
|
----------------------------------------------
|
||||||
|
- Update item access time less often.
|
||||||
|
- Don't try to start akonadiserver if mysqld is not installed
|
||||||
|
- Allow to fetch available items even if there are errors in some of the items.
|
||||||
|
- Properly restrict the external part removal to the deleted collection.
|
||||||
|
- Support checking the cache for payloads in the FETCH command.
|
||||||
|
- Add infrastructure to track client capabilities.
|
||||||
|
- Allow to disable the cache verification on retrieval.
|
||||||
|
- fsck: move orphaned pim items to lost+found, delete orphaned pim item flags.
|
||||||
|
- Introduce NotificationMessageV2 that supports batch operations on set of entities.
|
||||||
|
- Fix build with Boost >= 1.53.
|
||||||
|
- Fix a runtime issue with MySQL >= 5.6 (MySQL >= 5.1.3 is now the minimum version).
|
||||||
|
|
||||||
|
1.9.2 05-May-2013
|
||||||
|
---------------------------------------------
|
||||||
|
- Add option to FETCH to ignore external retrieval failures.
|
||||||
|
- Properly restrict external payload removal.
|
||||||
|
- Add buildsystem option to choose between Qt4 and Qt5.
|
||||||
|
|
||||||
|
1.9.1 02-March-2013
|
||||||
|
---------------------------------------------
|
||||||
|
- Disable query cache for Sqlite.
|
||||||
|
- Handle missing mysqld better.
|
||||||
|
- Ignore my.cnf settings when using the internal MySQL server.
|
||||||
|
|
||||||
|
1.9.0 23-December-2012
|
||||||
|
---------------------------------------------
|
||||||
|
- Respect collection cache policy refresh interval for collection tree sync.
|
||||||
|
- Fix initialization of PostgreSQL database.
|
||||||
|
- Correctly count items flags in virtual collections.
|
||||||
|
- Notify parent virtual collections about item changes.
|
||||||
|
- Require CMake >= 2.8.8.
|
||||||
|
- Remove dependency to Automoc4.
|
||||||
|
- Support Qt 5.
|
||||||
|
|
||||||
|
1.8.80 12-November-2012
|
||||||
|
---------------------------------------------
|
||||||
|
- Recover from lost external payload files.
|
||||||
|
- Improve the virtual collections handling.
|
||||||
|
- Notify clients about database schema updates.
|
||||||
|
- Reduce item access time updates.
|
||||||
|
- Make use of referential integrity if supported by the database backend.
|
||||||
|
- Add prepared query cache.
|
||||||
|
- Many code and queries optimizations.
|
||||||
|
|
||||||
|
1.8.1 14-October-2012
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix payload loss on some move/copy scenarios.
|
||||||
|
- Improve error reporting for failed item retrievals.
|
||||||
|
|
||||||
|
1.8.0 25-July-2012
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix deadlock in ad-hoc Nepomuk searches.
|
||||||
|
|
||||||
|
1.7.95 11-July-2012
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix Nepomuk queries getting stuck if Nepomuk service crashes.
|
||||||
|
- Fix unecessary remote retrieval of already cached item parts.
|
||||||
|
- Reset RID/RREV during cross-resource collection moves.
|
||||||
|
- Increase timeout for remote item retrieval.
|
||||||
|
|
||||||
|
1.7.90 08-June-2012
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix handling of large SPARQL queries.
|
||||||
|
- Support cleanup of orphaned resources in the consistency checker.
|
||||||
|
- Support compilation with Clang.
|
||||||
|
|
||||||
|
1.7.2 31-March-2012
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix and optimize searching via Nepomuk.
|
||||||
|
|
||||||
|
1.7.1 03-March-2012
|
||||||
|
---------------------------------------------
|
||||||
|
- Don't truncate SPARQL queries in virtual collections.
|
||||||
|
- Optimize change notifications for deleted collection attributes.
|
||||||
|
- Fix possible data loss during item copy/move operations.
|
||||||
|
|
||||||
|
1.7.0 23-January-2012
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix search result retrieval from Nepomuk.
|
||||||
|
|
||||||
|
1.6.90 20-December-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- Support for PostgreSQL >= 9.
|
||||||
|
- Improve RFC 3501 compatibility in LOGIN and non-silent SELECT commands.
|
||||||
|
- Add support for running multiple instance concurrently in the same user session.
|
||||||
|
- Update agent interface to include collectionTreeSynchronized signal.
|
||||||
|
- Add consistency checker system.
|
||||||
|
- Add support for database vacuuming.
|
||||||
|
- Various optimizations to reduce the number of SQL queries.
|
||||||
|
|
||||||
|
1.6.2 03-October-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- Do not update item revision if only the RID or RREV changed.
|
||||||
|
- Fix usage of wrong ids for part filenames.
|
||||||
|
- Only set item dirty flag if the payload changed.
|
||||||
|
- Only drop content mimetype for unsubscribed collections in LIST/LSUB.
|
||||||
|
|
||||||
|
1.6.1 15-September-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix crash on agent launcher exit.
|
||||||
|
- Fix valgrind-ing agents running in the agent launcher.
|
||||||
|
- Fix restarting of agents in broken state.
|
||||||
|
- Fix pipe naming on multi-user Windows systems.
|
||||||
|
- Raise MySQL timeout.
|
||||||
|
|
||||||
|
1.6.0 10-July-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- Enable external payload storage unconditionally.
|
||||||
|
- Treat single UID/RID fetches as error if the result set is empty.
|
||||||
|
|
||||||
|
1.5.80 21-May-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- WinCE database performance improvements.
|
||||||
|
- Include destination resource in move notifications.
|
||||||
|
- Fix crash in protocol parser.
|
||||||
|
- Fix possible race on accessing table caches.
|
||||||
|
- Use QStringBuilder if available.
|
||||||
|
- Improved notification message API.
|
||||||
|
|
||||||
|
1.5.3 07-May-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix crash when copying collections into themselves.
|
||||||
|
|
||||||
|
1.5.2 05-April-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix XdgBaseDirs reporting duplicated paths.
|
||||||
|
- Use correct database name when using internal MySQL.
|
||||||
|
|
||||||
|
1.5.1 28-February-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- Unbreak searching with Nepomuk 4.6.
|
||||||
|
|
||||||
|
1.5.0 22-January-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix Boost related build issues on Windows.
|
||||||
|
- Hide akonadi_agent_launcher from Mac OS X dock.
|
||||||
|
|
||||||
|
1.4.95 07-January-2011
|
||||||
|
---------------------------------------------
|
||||||
|
- Optimize notification compression.
|
||||||
|
- Consider ignore flag when calculating collection statistics.
|
||||||
|
- Fix item payload size calculation.
|
||||||
|
- Improved FETCH response order heuristic.
|
||||||
|
- Fix Strigi-based persistent search folders.
|
||||||
|
- Fix error propagation in FETCH command handler.
|
||||||
|
|
||||||
|
1.4.90 20-December-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Set agent status for crashed instances.
|
||||||
|
- Allow to restart crashed agent instances.
|
||||||
|
- Automatically recover from loss of the resource table.
|
||||||
|
- Allow to specify the query language in persistent search commands.
|
||||||
|
- Fix leak of notification sources.
|
||||||
|
|
||||||
|
1.4.85 18-December-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix agent server startup race.
|
||||||
|
- Allow to globally enable/disable the agent server.
|
||||||
|
- Fix autostart of agents running in the agent server.
|
||||||
|
- Fix agent configuration when running in the agent server.
|
||||||
|
- Fix agent server shutdown crash.
|
||||||
|
- Put sockets into /tmp to support AFS/NFS home directories.
|
||||||
|
- Fix access rights on persistent search folders.
|
||||||
|
- Add support for sub-collection tree syncs in resource interface.
|
||||||
|
|
||||||
|
1.4.80 21-November-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Experimental support for MeeGo.
|
||||||
|
- Return changed revision numbers in STORE response.
|
||||||
|
- Fix Nepomuk searches mixing up items and email attachments.
|
||||||
|
- Experimental Strigi search backend.
|
||||||
|
- Compensate for Nepomuk D-Bus API breakage.
|
||||||
|
- Fix parsing of serialization format version.
|
||||||
|
- Optimize collection statistics queries.
|
||||||
|
- Optimize protocol output generation.
|
||||||
|
- Optimize protocol parsing.
|
||||||
|
- Build-time configurable default database backend.
|
||||||
|
- Fix ancestor chain quoting.
|
||||||
|
- Fix finding of components on Windows in install location.
|
||||||
|
- New subscription interface for change notifications.
|
||||||
|
- Support for in-process agents and agent server.
|
||||||
|
- Support for Sqlite.
|
||||||
|
- Experimental support for ODBC-based database backends.
|
||||||
|
- Support Windows CE.
|
||||||
|
|
||||||
|
1.4.1 22-October-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Improve range query performance.
|
||||||
|
- Fix MySQL database upgrade happening too early.
|
||||||
|
- Fix MySQL database upgrade setting wrong priviledges.
|
||||||
|
- Fix non-index access slowing down server startup.
|
||||||
|
- ASAP parser performance optimizations
|
||||||
|
- Respect SocketDirectory setting also for database sockets.
|
||||||
|
- Allow $USER placeholder in SocketDirectory setting.
|
||||||
|
- Fix ASAP parser failing on non-zero serialization format versions.
|
||||||
|
|
||||||
|
1.4.0 31-July-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Add change notification for collection subscription state changes.
|
||||||
|
- Enable filesystem payload store by default.
|
||||||
|
- Fix unicode folder name encoding regression.
|
||||||
|
|
||||||
|
1.3.90 04-July-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Reset RIDs on inter-resource moves.
|
||||||
|
- Optimize disk space usage with internal MySQL.
|
||||||
|
- Improve error reporting of the Akonadi remote debugging server.
|
||||||
|
- Fix moving collections into the collection root.
|
||||||
|
- Report PostgreSQL database errors in english independent of locale settings.
|
||||||
|
- Fix unicode collection name encoding.
|
||||||
|
- Optimize cache pruning with filesystem payload store.
|
||||||
|
- Fix automatic migration between database and filesystem payload store.
|
||||||
|
|
||||||
|
1.3.85 09-June-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Avoid unneeded full resource sync when using sync-on-demand cache policies.
|
||||||
|
- Fix crash when using D-Bus session bus in a secondary thread.
|
||||||
|
- Reduce emission of unneccessary change notifications.
|
||||||
|
- Fix empty filename use in fs backend.
|
||||||
|
|
||||||
|
1.3.80 27-May-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix unicode collection name encoding.
|
||||||
|
- Support HRID-based FETCH commands.
|
||||||
|
- Fix Nepomuk-based persistent searches when Nepomuk was not running during Akonadi startup.
|
||||||
|
- Fix compilation on Windows CE.
|
||||||
|
- Optimize item retrieval queries.
|
||||||
|
- Support modification of existing persistent searches.
|
||||||
|
- Support different query languages for persistent searches.
|
||||||
|
- Fix PostgreSQL shutdown.
|
||||||
|
- Add initial support for Sqlite.
|
||||||
|
- Fix premature command abortion.
|
||||||
|
- Fix parsing of cascaded lists.
|
||||||
|
- Support for mysql_update_db.
|
||||||
|
- Support for mysql_install_db.
|
||||||
|
- Improved protocol tracing for akonadiconsole.
|
||||||
|
- Support MySQL backend on Maemo.
|
||||||
|
- Allow RID changes only to the owning resource.
|
||||||
|
- Add Akonadi remote debugging server.
|
||||||
|
- Add support for marking chaced payloads as invalid.
|
||||||
|
- Add support for remove revision property.
|
||||||
|
- Fix MySQL connection loss after 8 hours of inactivity.
|
||||||
|
- Fix D-Bus race on server startup.
|
||||||
|
- Fix internal MySQL on Windows.
|
||||||
|
- Fix config and data file location on Windows.
|
||||||
|
- Fix PostgreSQL startup when using internal server.
|
||||||
|
- Refactor database configuration abstraction.
|
||||||
|
|
||||||
|
1.3.1 09-February-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix D-Bus connection leak in Nepomuk search backend.
|
||||||
|
- Disable slow query logging by default for internal MySQL.
|
||||||
|
|
||||||
|
1.3.0 20-January-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Work around D-Bus bug that could cause SEARCH to hang.
|
||||||
|
|
||||||
|
1.2.90 06-January-2010
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix change notifications for search results.
|
||||||
|
- Fix database creation with PostgreSQL.
|
||||||
|
- Fix copying of item flags.
|
||||||
|
- Fix internal MySQL shutdown.
|
||||||
|
- Support PostgreSQL in internal mode.
|
||||||
|
- Fix table name case mismatch.
|
||||||
|
|
||||||
|
1.2.80 01-December-2009
|
||||||
|
---------------------------------------------
|
||||||
|
- Support for collection content type filtering as part of LIST.
|
||||||
|
- Adapt to Nepomuk query service changes.
|
||||||
|
- Experimental support for PostgreSQL.
|
||||||
|
- Support for preprocessor agents.
|
||||||
|
- Support for distributed searching.
|
||||||
|
- Support for agents creating virtual collections.
|
||||||
|
- Protocol parser fixes for non-Linux/non-KDE clients.
|
||||||
|
- Support for single-shot searches using the Nepomuk query service.
|
||||||
|
- Support HRID-based LIST operations.
|
||||||
|
- Support RID-based MOVE, COLMOVE, LINK and UNLINK opertions.
|
||||||
|
- Respect cache-only retrieval also regarding on-demand syncing.
|
||||||
|
- Add configuration accepted/rejected signals to the agent interface.
|
||||||
|
- Fix change notification compression when using modified parts sets.
|
||||||
|
- Use one retrieval pipeline per resource.
|
||||||
|
- Reduce unecessary change notification on flag changes.
|
||||||
|
- Fix RID quoting.
|
||||||
|
- Fix resource creating race for autostarted agents.
|
||||||
|
- Create new database also when using external db servers.
|
||||||
|
- Return the created result collection when creating a persistent search.
|
||||||
|
|
||||||
|
1.2.1 28-August-2009
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix item creation with RID's containing a ']'.
|
||||||
|
- Fix ASAP parser not reading the entire command.
|
||||||
|
|
||||||
|
1.2.0 28-June-2009
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix attribute joining in collection list results.
|
||||||
|
- Buildsystem fixes for Mac OS.
|
||||||
|
- Do not show a console window for akonadi_control on Windows.
|
||||||
|
|
||||||
|
1.1.95 23-June-2009
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix item size handling.
|
||||||
|
- Add support for retrieving collection statistics as part
|
||||||
|
of the AKLIST/AKLSUB commands.
|
||||||
|
- Add support for collection size statistics.
|
||||||
|
- Build fixes for Windows.
|
||||||
|
- Support RID-based operations for CREATE, MODIFY and DELETE.
|
||||||
|
- Avoid emitting unecessary change notifications when
|
||||||
|
modifying items or collections.
|
||||||
|
- Add COLMOVE command.
|
||||||
|
- Reduce number of database writes when modifying a collection.
|
||||||
|
- Fix parsing of attributes containing CR or LF characters.
|
||||||
|
|
||||||
|
1.1.90 03-June-2009
|
||||||
|
---------------------------------------------
|
||||||
|
- Return the storage location for items in FETCH responses
|
||||||
|
- Fix remode identifier encoding problems
|
||||||
|
- Fix infinite loop when parsing RID lists
|
||||||
|
- Fix parsing errors on stray newlines
|
||||||
|
- Support RID-based operations for STORE and MOVE
|
||||||
|
- Fix race on resource creation
|
||||||
|
- Provide modified item parts in change notifications
|
||||||
|
- Build system fixes
|
||||||
|
|
||||||
|
1.1.85 05-May-2009
|
||||||
|
---------------------------------------------
|
||||||
|
- Improved CMake scripts so it is possible to detect
|
||||||
|
the Akonadi version in projects that depend on it.
|
||||||
|
- Simplified the check for existance of tables.
|
||||||
|
- Add a dedicated item deletion command, to get rid of
|
||||||
|
the old STORE/EXPUNGE which was extremely inefficient.
|
||||||
|
- Some fixes to support sqlite in the future.
|
||||||
|
- Soprano is required now.
|
||||||
|
- Qt 4.5.0 is required now.
|
||||||
|
- Support for collection retrieval by remote identifier.
|
||||||
|
- Support for item retrieval based on the remote identifier.
|
||||||
|
- Less useless debug output.
|
||||||
|
- Fixed leak on socket error.
|
||||||
|
- Various smaller bug fixes, see ChangeLog for a list.
|
||||||
|
- Support for writing large payloads to a file.
|
||||||
|
- New Item retrieval code.
|
||||||
|
- Added a streaming IMAP parser, and ported code the use it.
|
||||||
|
- Add support for manually restarting an agent instance.
|
||||||
|
|
||||||
|
1.1.2 30-Apr-2009
|
||||||
|
---------------------------------------------
|
||||||
|
- Avoid DBUS lockups, reported at: https://bugs.kde.org/182198
|
||||||
|
- Update user mysql.conf only if global/local one's are newer
|
||||||
|
|
||||||
|
1.1.1 21-Jan-2009
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix code that was not executed in a release build.
|
||||||
|
- Require CMake 2.6.0 which fixes boost detection.
|
||||||
|
- Don't try to restart an agent that has been deleted.
|
||||||
|
|
||||||
|
1.1.0 03-Jan-2009
|
||||||
|
---------------------------------------------
|
||||||
|
- Restart agents when their executable changed.
|
||||||
|
- Buildsystem fixes to find and link boost on all platforms.
|
||||||
|
- Improvements to the startup to prevent partial startup.
|
||||||
|
- Include revision number in the version string when building from SVN.
|
||||||
|
- Shut down when we lost the connection to the D-Bus session bus.
|
||||||
|
- add some basic handling of command line args.
|
||||||
|
- Add a D-Bus call to flush the notification queue.
|
||||||
|
- Automatically fix world-writeable mySQL config files.
|
||||||
|
- Fix for FreeBSD mysql path.
|
||||||
|
|
||||||
|
1.0.81 16-Dec-2008
|
||||||
|
---------------------------------------------
|
||||||
|
- Restore protocol backward compatibility with Akonadi 1.0.x servers.
|
||||||
|
- Build system fixes.
|
||||||
|
- Fix compiler warnings.
|
||||||
|
- Fall back to the default server path if the configured one points
|
||||||
|
to a non-existing file.
|
||||||
|
|
||||||
|
1.0.80 19-Nov-2008
|
||||||
|
---------------------------------------------
|
||||||
|
- Query agent status information asynchronously and answer all queries from
|
||||||
|
cached values, reduces the risk of an agents blocking the Akonadi server.
|
||||||
|
- Increase mysql limits to more realistical values.
|
||||||
|
- Don't mark all new items as recent.
|
||||||
|
- Changes so it can store the size of an item.
|
||||||
|
- Better error detection.
|
||||||
|
- Prevent translated month names in the protocol.
|
||||||
|
- Some build fixes.
|
||||||
|
- Handle multiline output correctly.
|
||||||
|
- Terminate the control process when the server process failed to start.
|
||||||
|
- Add the ability to debug or valgrind a resource right from the
|
||||||
|
beginning, similar to the way this can be done with KIO slaves.
|
||||||
|
- Fix fetching of linked items in arbitrary collections.
|
||||||
|
- Add notification support for item references in virtual collections.
|
||||||
|
- Add LINK/UNLINK commands to edit references to items in virtual collections.
|
||||||
|
- Add a way to notify agents that their configuration has been changed remotely.
|
||||||
|
- Make sure that all modification times are stored in UTC time zone.
|
||||||
|
- Unquoted date time with a lenght of 26 characters was not parsed properly.
|
||||||
|
- Add serverside timestamp support for items.
|
||||||
|
|
||||||
|
1.0.0 22-July-2008
|
||||||
|
---------------------------------------------
|
||||||
|
- First official stable release
|
||||||
|
- Bugfix: Unquoted date time with a lenght of
|
||||||
|
26 characters was not parsed properly.
|
||||||
|
- Add serverside timestamp support for items.
|
||||||
|
- Build system fixes (windows & automoc)
|
||||||
|
|
||||||
|
0.82.0 18-June-2008
|
||||||
|
---------------------------------------------
|
||||||
|
- Several build and installation fixes for windows and mac.
|
||||||
|
- Some improvements in the build system.
|
||||||
|
- Add item part namespaces.
|
||||||
|
- Implemented all the fetch modes advertised in ItemFetchScope.
|
||||||
|
- Notify already running clieants about all found types during startup.
|
||||||
|
|
||||||
|
0.81.0 10-May-2008
|
||||||
|
---------------------------------------------
|
||||||
|
- Fix bug where full part was not fetched when a partial part was available already.
|
||||||
|
- Collection parsing optimalisation.
|
||||||
|
- Optimization for quoted string parsing.
|
||||||
|
- Use org.freedesktop namespace, instead of org.kde for the dbus interfaces.
|
||||||
|
- Add support for version numbers for database and protocol.
|
||||||
|
- Fixed foreach misusage.
|
||||||
|
- Depend on external automoc package instead of a copy.
|
||||||
|
|
||||||
|
0.80.0 24-Apr-2008
|
||||||
|
---------------------------------------------
|
||||||
|
- Initial release
|
36
akonadi/README
Normal file
36
akonadi/README
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
Akonadi
|
||||||
|
========
|
||||||
|
|
||||||
|
What is Akonadi?
|
||||||
|
------------------
|
||||||
|
Akonadi is a PIM layer, which provides an asynchronous API to access all kind
|
||||||
|
of PIM data (e.g. mails, contacts, events, todos etc.).
|
||||||
|
|
||||||
|
It consists of several processes (generally called the Akonadi server) and a
|
||||||
|
library (called client library) which encapsulates the communication
|
||||||
|
between the client and the server.
|
||||||
|
|
||||||
|
This directory contains the sources of the Akonadi server and all the infrastructure
|
||||||
|
that is needed to build the client libraries and the application which want to make
|
||||||
|
use of Akonadi.
|
||||||
|
|
||||||
|
Structure
|
||||||
|
----------
|
||||||
|
|
||||||
|
* cmake/
|
||||||
|
Contains the cmake checks that are needed to build the server.
|
||||||
|
|
||||||
|
* interfaces/
|
||||||
|
Contains the dbus interface descriptions that are used by the
|
||||||
|
client library to control the Akonadi server or request status
|
||||||
|
information.
|
||||||
|
|
||||||
|
* libs/
|
||||||
|
Contains the sources of a private library which provides utils
|
||||||
|
that are used by both, the Akonadi server and the client library.
|
||||||
|
|
||||||
|
* server/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
See INSTALL for installation instructions.
|
53
akonadi/README.sqlite
Normal file
53
akonadi/README.sqlite
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
== PREFACE ==
|
||||||
|
|
||||||
|
The reason we have our own QtSql Sqlite driver here is because the one shipped
|
||||||
|
with Qt misses a bunch of multi-threading fixes crucial for Akonadi. Of course,
|
||||||
|
these changes should be pushed upstream eventually.
|
||||||
|
|
||||||
|
== INSTALL ==
|
||||||
|
When Sqlite is found, the custom driver will be build and installed in:
|
||||||
|
|
||||||
|
${CMAKE_INSTALL_PREFIX}/lib/plugins/sqldrivers or ${QT_PLUGINS_DIR}/sqldrivers
|
||||||
|
if you enable the INSTALL_QSQLITE_IN_QT_PREFIX option when running CMake.
|
||||||
|
|
||||||
|
The next thing you have to do is add that path (if it isn't already) to your
|
||||||
|
QT_PLUGIN_PATH environment variable.
|
||||||
|
|
||||||
|
Now you should be able to configure the QSQLITE3 driver in akonadiserverrc.
|
||||||
|
|
||||||
|
== PROBLEMS ==
|
||||||
|
|
||||||
|
One of the problematic code paths seems to be:
|
||||||
|
|
||||||
|
server/src/handler/fetch.cpp:161-201
|
||||||
|
|
||||||
|
In this part the code is iterating over the results of an still active SELECT
|
||||||
|
query and during this iteration it also tries to do INSERT/UPDATE queries. This
|
||||||
|
means that there is probably a SHARED lock for the reading and a PENDING lock
|
||||||
|
for the writing queries. For sqlite to be able to write to the db it needs an
|
||||||
|
EXCLUSIVE lock. A PENDING lock only gets inclusive when all SHARED locks are
|
||||||
|
gone.
|
||||||
|
|
||||||
|
A possible solution might be to store the results of the SELECT query into
|
||||||
|
memory, close the query and than start the inserts/updates.
|
||||||
|
|
||||||
|
|
||||||
|
== SQLITE INFO ==
|
||||||
|
|
||||||
|
From www.sqlite.org: (see qsqlite/src/qsql_sqlite.cpp:525-529)
|
||||||
|
Run-time selection of threading mode
|
||||||
|
|
||||||
|
If single-thread mode has not been selected at compile-time or start-time, then
|
||||||
|
individual database connections can be created as either multi-thread or
|
||||||
|
serialized. It is not possible to downgrade an individual database connection
|
||||||
|
to single-thread mode. Nor is it possible to escalate an individual database
|
||||||
|
connection if the compile-time or start-time mode is single-thread.
|
||||||
|
|
||||||
|
The threading mode for an individual database connection is determined by flags
|
||||||
|
given as the third argument to sqlite3_open_v2(). The SQLITE_OPEN_NOMUTEX flag
|
||||||
|
causes the database connection to be in the multi-thread mode and the
|
||||||
|
SQLITE_OPEN_FULLMUTEX flag causes the connection to be in serialized mode. If
|
||||||
|
neither flag is specified or if sqlite3_open() or sqlite3_open16() are used
|
||||||
|
instead of sqlite3_open_v2(), then the default mode determined by the
|
||||||
|
compile-time and start-time settings is used.
|
||||||
|
|
55
akonadi/agentserver/CMakeLists.txt
Normal file
55
akonadi/agentserver/CMakeLists.txt
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_ENABLE_EXCEPTIONS}")
|
||||||
|
|
||||||
|
# Agent server
|
||||||
|
set(akonadi_agent_server_srcs
|
||||||
|
agentpluginloader.cpp
|
||||||
|
agentserver.cpp
|
||||||
|
agentthread.cpp
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(akonadi_agent_server ${akonadi_agent_server_srcs})
|
||||||
|
|
||||||
|
target_link_libraries(akonadi_agent_server
|
||||||
|
akonadi_shared
|
||||||
|
${QT_QTGUI_LIBRARIES}
|
||||||
|
${QT_QTDBUS_LIBRARY}
|
||||||
|
${AKONADI_SYSTEM_LIBS}
|
||||||
|
${AKONADI_PROTOCOLINTERNALS_LIBS}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(akonadi_agent_server ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||||
|
|
||||||
|
# Agent plugin launcher
|
||||||
|
set(akonadi_agent_launcher_SRCS
|
||||||
|
agentpluginloader.cpp
|
||||||
|
agentlauncher.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(akonadi_agent_launcher MACOSX_BUNDLE ${akonadi_agent_launcher_SRCS})
|
||||||
|
target_link_libraries(akonadi_agent_launcher
|
||||||
|
akonadi_shared
|
||||||
|
${QT_QTGUI_LIBRARIES}
|
||||||
|
${AKONADI_SYSTEM_LIBS}
|
||||||
|
${AKONADI_PROTOCOLINTERNALS_LIBS}
|
||||||
|
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(Q_WS_MAC)
|
||||||
|
set_target_properties(akonadi_agent_launcher PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template)
|
||||||
|
set_target_properties(akonadi_agent_launcher PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.agentlauncher")
|
||||||
|
set_target_properties(akonadi_agent_launcher PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Akonadi Agent Launcher")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Install both helper apps.
|
||||||
|
if(Q_WS_MAC)
|
||||||
|
install(TARGETS akonadi_agent_launcher
|
||||||
|
DESTINATION ${AKONADI_BUNDLE_PATH})
|
||||||
|
else()
|
||||||
|
install(TARGETS akonadi_agent_launcher
|
||||||
|
DESTINATION ${BIN_INSTALL_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS akonadi_agent_server
|
||||||
|
DESTINATION ${BIN_INSTALL_DIR})
|
||||||
|
|
3
akonadi/agentserver/TODO
Normal file
3
akonadi/agentserver/TODO
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
* When the AgentServer process crashes and is restarted by ProcessControl,
|
||||||
|
somehow the agents/resources that where running must be restarted as
|
||||||
|
well.
|
61
akonadi/agentserver/agentlauncher.cpp
Normal file
61
akonadi/agentserver/agentlauncher.cpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Bertjan Broeksema <broeksema@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "agentpluginloader.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main( int argc, char *argv[] )
|
||||||
|
{
|
||||||
|
QApplication app( argc, argv );
|
||||||
|
app.setQuitOnLastWindowClosed( false );
|
||||||
|
|
||||||
|
if ( app.arguments().size() != 3 ) { // Expected usage: ./agent_launcher ${plugin_name} ${identifier}
|
||||||
|
qDebug() << "Invalid usage: expected: ./agent_launcher pluginName agentIdentifier";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString agentPluginName = app.arguments().at( 1 );
|
||||||
|
const QString agentIdentifier = app.arguments().at( 2 );
|
||||||
|
|
||||||
|
AgentPluginLoader loader;
|
||||||
|
QPluginLoader *factory = loader.load( agentPluginName );
|
||||||
|
if ( factory == 0 ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *instance = 0;
|
||||||
|
const bool invokeSucceeded = QMetaObject::invokeMethod( factory->instance(),
|
||||||
|
"createInstance",
|
||||||
|
Qt::DirectConnection,
|
||||||
|
Q_RETURN_ARG( QObject*, instance ),
|
||||||
|
Q_ARG( QString, agentIdentifier ) );
|
||||||
|
if ( invokeSucceeded ) {
|
||||||
|
qDebug() << "Agent instance created in separate process.";
|
||||||
|
} else {
|
||||||
|
qDebug() << "Agent instance creation in separate process failed";
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int rv = app.exec();
|
||||||
|
delete instance;
|
||||||
|
return rv;
|
||||||
|
}
|
52
akonadi/agentserver/agentpluginloader.cpp
Normal file
52
akonadi/agentserver/agentpluginloader.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Bertjan Broeksema <broeksema@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#include "agentpluginloader.h"
|
||||||
|
|
||||||
|
#include "libs/xdgbasedirs_p.h"
|
||||||
|
#include "shared/akdebug.h"
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
AgentPluginLoader::~AgentPluginLoader()
|
||||||
|
{
|
||||||
|
qDeleteAll( m_pluginLoaders );
|
||||||
|
m_pluginLoaders.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPluginLoader *AgentPluginLoader::load( const QString &pluginName )
|
||||||
|
{
|
||||||
|
const QString pluginFile = XdgBaseDirs::findPluginFile( pluginName );
|
||||||
|
if ( pluginFile.isEmpty() ) {
|
||||||
|
akError() << Q_FUNC_INFO << "plugin file:" << pluginName << "not found!";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_pluginLoaders.contains( pluginFile ) ) {
|
||||||
|
return m_pluginLoaders.value( pluginFile );
|
||||||
|
} else {
|
||||||
|
QPluginLoader *loader = new QPluginLoader( pluginFile );
|
||||||
|
if ( !loader->load() ) {
|
||||||
|
akError() << Q_FUNC_INFO << "Failed to load agent: " << loader->errorString();
|
||||||
|
delete loader;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
m_pluginLoaders.insert( pluginFile, loader );
|
||||||
|
return loader;
|
||||||
|
}
|
||||||
|
}
|
46
akonadi/agentserver/agentpluginloader.h
Normal file
46
akonadi/agentserver/agentpluginloader.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Bertjan Broeksema <broeksema@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#ifndef AGENTPLUGINLOADER_H
|
||||||
|
#define AGENTPLUGINLOADER_H
|
||||||
|
|
||||||
|
#include <QtCore/QHash>
|
||||||
|
#include <QtCore/QPluginLoader>
|
||||||
|
|
||||||
|
class AgentPluginLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Deletes all instantiated QPluginLoaders.
|
||||||
|
*/
|
||||||
|
~AgentPluginLoader();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the loader for plugins with @param pluginName. Callers must not
|
||||||
|
take ownership over the returned loader. Loaders will be unloaded and deleted
|
||||||
|
when the AgentPluginLoader goes out of scope/gets deleted.
|
||||||
|
|
||||||
|
@return the plugin for @param pluginName or 0 if the plugin is not found.
|
||||||
|
*/
|
||||||
|
QPluginLoader *load( const QString &pluginName );
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash<QString, QPluginLoader *> m_pluginLoaders;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AGENTPLUGINLOADER_H
|
134
akonadi/agentserver/agentserver.cpp
Normal file
134
akonadi/agentserver/agentserver.cpp
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "agentserver.h"
|
||||||
|
|
||||||
|
#include "agentthread.h"
|
||||||
|
#include "libs/xdgbasedirs_p.h"
|
||||||
|
#include "libs/protocol_p.h"
|
||||||
|
#include "shared/akdebug.h"
|
||||||
|
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QPluginLoader>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
#include <QtDBus/QDBusConnection>
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
AgentServer::AgentServer( QObject *parent )
|
||||||
|
: QObject( parent )
|
||||||
|
, m_processingConfigureRequests( false )
|
||||||
|
, m_quiting( false )
|
||||||
|
{
|
||||||
|
QDBusConnection::sessionBus().registerObject( QLatin1String( AKONADI_DBUS_AGENTSERVER_PATH ),
|
||||||
|
this, QDBusConnection::ExportScriptableSlots );
|
||||||
|
}
|
||||||
|
|
||||||
|
AgentServer::~AgentServer()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
if ( !m_quiting ) {
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentServer::agentInstanceConfigure( const QString &identifier, qlonglong windowId )
|
||||||
|
{
|
||||||
|
m_configureQueue.enqueue( ConfigureInfo( identifier, windowId ) );
|
||||||
|
if ( !m_processingConfigureRequests ) { // Start processing the requests if needed.
|
||||||
|
QTimer::singleShot( 0, this, SLOT(processConfigureRequest()) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AgentServer::started( const QString &identifier ) const
|
||||||
|
{
|
||||||
|
return m_agents.contains( identifier );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentServer::startAgent( const QString &identifier, const QString &typeIdentifier, const QString &fileName )
|
||||||
|
{
|
||||||
|
akDebug() << Q_FUNC_INFO << identifier << typeIdentifier << fileName;
|
||||||
|
|
||||||
|
//First try to load it staticly
|
||||||
|
Q_FOREACH ( QObject *plugin, QPluginLoader::staticInstances() ) {
|
||||||
|
if ( plugin->objectName() == fileName ) {
|
||||||
|
AgentThread *thread = new AgentThread( identifier, plugin, this );
|
||||||
|
m_agents.insert( identifier, thread );
|
||||||
|
thread->start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QPluginLoader *loader = m_agentLoader.load( fileName );
|
||||||
|
if ( loader == 0 ) {
|
||||||
|
return; // No plugin found, debug output in AgentLoader.
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT( loader->isLoaded() );
|
||||||
|
|
||||||
|
AgentThread *thread = new AgentThread( identifier, loader->instance(), this );
|
||||||
|
m_agents.insert( identifier, thread );
|
||||||
|
thread->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentServer::stopAgent( const QString &identifier )
|
||||||
|
{
|
||||||
|
if ( !m_agents.contains( identifier ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AgentThread *thread = m_agents.take( identifier );
|
||||||
|
thread->quit();
|
||||||
|
thread->wait();
|
||||||
|
delete thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentServer::quit()
|
||||||
|
{
|
||||||
|
Q_ASSERT( !m_quiting );
|
||||||
|
m_quiting = true;
|
||||||
|
|
||||||
|
QMutableHashIterator<QString, AgentThread *> it( m_agents );
|
||||||
|
while ( it.hasNext() ) {
|
||||||
|
it.next();
|
||||||
|
stopAgent( it.key() );
|
||||||
|
}
|
||||||
|
|
||||||
|
QCoreApplication::instance()->quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentServer::processConfigureRequest()
|
||||||
|
{
|
||||||
|
if ( m_processingConfigureRequests ) {
|
||||||
|
return; // Protect against reentrancy
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processingConfigureRequests = true;
|
||||||
|
|
||||||
|
while ( !m_configureQueue.empty() ) {
|
||||||
|
const ConfigureInfo info = m_configureQueue.dequeue();
|
||||||
|
// call configure on the agent with id info.first for windowId info.second.
|
||||||
|
Q_ASSERT( m_agents.contains( info.first ) );
|
||||||
|
AgentThread *thread = m_agents.value( info.first );
|
||||||
|
thread->configure( info.second );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processingConfigureRequests = false;
|
||||||
|
}
|
64
akonadi/agentserver/agentserver.h
Normal file
64
akonadi/agentserver/agentserver.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_AGENTSERVER_H
|
||||||
|
#define AKONADI_AGENTSERVER_H
|
||||||
|
|
||||||
|
#include "agentpluginloader.h"
|
||||||
|
|
||||||
|
#include <QtCore/QHash>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QQueue>
|
||||||
|
|
||||||
|
namespace Akonadi {
|
||||||
|
|
||||||
|
class AgentThread;
|
||||||
|
|
||||||
|
class AgentServer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_CLASSINFO( "D-Bus Interface", "org.freedesktop.Akonadi.AgentServer" )
|
||||||
|
|
||||||
|
typedef QPair<QString, qlonglong> ConfigureInfo;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AgentServer( QObject *parent = 0 );
|
||||||
|
~AgentServer();
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
Q_SCRIPTABLE void agentInstanceConfigure( const QString &identifier, qlonglong windowId );
|
||||||
|
Q_SCRIPTABLE bool started( const QString &identifier ) const;
|
||||||
|
Q_SCRIPTABLE void startAgent( const QString &identifier, const QString &typeIdentifier, const QString &fileName );
|
||||||
|
Q_SCRIPTABLE void stopAgent( const QString &identifier );
|
||||||
|
Q_SCRIPTABLE void quit();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void processConfigureRequest();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash<QString, AgentThread *> m_agents;
|
||||||
|
QQueue<ConfigureInfo> m_configureQueue;
|
||||||
|
AgentPluginLoader m_agentLoader;
|
||||||
|
bool m_processingConfigureRequests;
|
||||||
|
bool m_quiting;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
63
akonadi/agentserver/agentthread.cpp
Normal file
63
akonadi/agentserver/agentthread.cpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "agentthread.h"
|
||||||
|
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QPluginLoader>
|
||||||
|
#include <QWidget> // Needed for WId
|
||||||
|
|
||||||
|
#include <shared/akdebug.h>
|
||||||
|
#include <qmetaobject.h>
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
AgentThread::AgentThread( const QString &identifier, QObject *factory, QObject *parent )
|
||||||
|
: QThread( parent )
|
||||||
|
, m_identifier( identifier )
|
||||||
|
, m_factory( factory )
|
||||||
|
, m_instance( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentThread::run()
|
||||||
|
{
|
||||||
|
const bool invokeSucceeded = QMetaObject::invokeMethod( m_factory,
|
||||||
|
"createInstance",
|
||||||
|
Qt::DirectConnection,
|
||||||
|
Q_RETURN_ARG( QObject*, m_instance ),
|
||||||
|
Q_ARG( QString, m_identifier ) );
|
||||||
|
if ( invokeSucceeded ) {
|
||||||
|
qDebug() << Q_FUNC_INFO << "agent instance created: " << m_instance;
|
||||||
|
} else {
|
||||||
|
qDebug() << Q_FUNC_INFO << "agent instance creation failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
exec();
|
||||||
|
delete m_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentThread::configure( qlonglong windowId )
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod( m_instance,
|
||||||
|
"configure",
|
||||||
|
Qt::DirectConnection,
|
||||||
|
Q_ARG( WId, (WId)windowId ) );
|
||||||
|
}
|
62
akonadi/agentserver/agentthread.h
Normal file
62
akonadi/agentserver/agentthread.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_AGENTTHREAD_H
|
||||||
|
#define AKONADI_AGENTTHREAD_H
|
||||||
|
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
|
||||||
|
namespace Akonadi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @short A class that encapsulates an agent instance inside a thread.
|
||||||
|
*/
|
||||||
|
class AgentThread : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new agent thread.
|
||||||
|
*
|
||||||
|
* @param identifier The unique identifier for this agent
|
||||||
|
* @param factory The factory object that creates the agent instance.
|
||||||
|
* @param parent The parent object.
|
||||||
|
*/
|
||||||
|
AgentThread( const QString &identifier, QObject *factory, QObject *parent = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the agent.
|
||||||
|
*
|
||||||
|
* @param windowId The parent window id for the config dialog.
|
||||||
|
*/
|
||||||
|
void configure( qlonglong windowId );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_identifier;
|
||||||
|
QObject *m_factory;
|
||||||
|
QObject *m_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
50
akonadi/agentserver/main.cpp
Normal file
50
akonadi/agentserver/main.cpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "agentserver.h"
|
||||||
|
|
||||||
|
#include <shared/akapplication.h>
|
||||||
|
#include <shared/akdbus.h>
|
||||||
|
#include <shared/akdebug.h>
|
||||||
|
|
||||||
|
#include <QtDBus/QDBusConnection>
|
||||||
|
#include <QtDBus/QDBusConnectionInterface>
|
||||||
|
#include <QtDBus/QDBusError>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main( int argc, char **argv )
|
||||||
|
{
|
||||||
|
AkGuiApplication app( argc, argv );
|
||||||
|
app.setDescription( QLatin1String( "Akonadi Agent Server\nDo not run manually, use 'akonadictl' instead to start/stop Akonadi." ) );
|
||||||
|
app.parseCommandLine();
|
||||||
|
qApp->setQuitOnLastWindowClosed( false );
|
||||||
|
|
||||||
|
if ( !QDBusConnection::sessionBus().interface()->isServiceRegistered( AkDBus::serviceName( AkDBus::ControlLock ) ) ) {
|
||||||
|
akError() << "Akonadi control process not found - aborting.";
|
||||||
|
akFatal() << "If you started akonadi_agent_server manually, try 'akonadictl start' instead.";
|
||||||
|
}
|
||||||
|
|
||||||
|
new Akonadi::AgentServer( &app );
|
||||||
|
|
||||||
|
if ( !QDBusConnection::sessionBus().registerService( AkDBus::serviceName( AkDBus::AgentServer ) ) ) {
|
||||||
|
akFatal() << "Unable to connect to dbus service: " << QDBusConnection::sessionBus().lastError().message();
|
||||||
|
}
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
35
akonadi/akonadi-mime.xml
Normal file
35
akonadi/akonadi-mime.xml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
It comes with ABSOLUTELY NO WARRANTY, to the extent permitted by law. You may
|
||||||
|
redistribute copies of update-mime-database under the terms of the GNU General
|
||||||
|
Public License. For more information about these matters, see the file named
|
||||||
|
COPYING.
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
Notes:
|
||||||
|
- the mime types in this file are valid with the version 0.20 of the
|
||||||
|
shared-mime-info package.
|
||||||
|
- the "fdo #xxxxx" are the wish in the freedesktop.org bug database to include
|
||||||
|
the mime type there.
|
||||||
|
-->
|
||||||
|
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||||
|
<mime-type type="application/x-vnd.akonadi.calendar.event">
|
||||||
|
<sub-class-of type="text/calendar"/>
|
||||||
|
<comment>iCal Calendar Event Component</comment>
|
||||||
|
</mime-type>
|
||||||
|
<mime-type type="application/x-vnd.akonadi.calendar.freebusy">
|
||||||
|
<sub-class-of type="text/calendar"/>
|
||||||
|
<comment>iCal Calendar FreeBusy Component</comment>
|
||||||
|
</mime-type>
|
||||||
|
<mime-type type="application/x-vnd.akonadi.calendar.journal">
|
||||||
|
<sub-class-of type="text/calendar"/>
|
||||||
|
<comment>iCal Calendar Journal Component</comment>
|
||||||
|
</mime-type>
|
||||||
|
<mime-type type="application/x-vnd.akonadi.calendar.todo">
|
||||||
|
<sub-class-of type="text/calendar"/>
|
||||||
|
<comment>iCal Calendar TODO Component</comment>
|
||||||
|
</mime-type>
|
||||||
|
<mime-type type="application/x-vnd.akonadi.collection.virtual">
|
||||||
|
<comment>Virtual Akonadi Collection</comment>
|
||||||
|
</mime-type>
|
||||||
|
</mime-info>
|
7
akonadi/akonadi-prefix.h.cmake
Normal file
7
akonadi/akonadi-prefix.h.cmake
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/* This file contains all the paths that change when changing the installation prefix */
|
||||||
|
|
||||||
|
#define AKONADIPREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||||
|
#define AKONADIDATA "${SHARE_INSTALL_PREFIX}"
|
||||||
|
#define AKONADICONFIG "${CONFIG_INSTALL_DIR}"
|
||||||
|
#define AKONADILIB "${LIB_INSTALL_DIR}"
|
||||||
|
#define AKONADIBUNDLEPATH "${AKONADI_BUNDLE_PATH}"
|
11
akonadi/akonadi.pc.cmake
Normal file
11
akonadi/akonadi.pc.cmake
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
libdir=@LIB_INSTALL_DIR@
|
||||||
|
includedir=@CMAKE_INSTALL_PREFIX@/include
|
||||||
|
|
||||||
|
Name: Akonadi
|
||||||
|
Description: Akonadi server and infrastructure needed to build client libraries and applications
|
||||||
|
Version: @AKONADI_VERSION@
|
||||||
|
Requires: QtCore QtSql QtDBus
|
||||||
|
Libs: -L${libdir} -lakonadiprotocolinternals
|
||||||
|
Cflags: -I${includedir}
|
15
akonadi/asapcat/CMakeLists.txt
Normal file
15
akonadi/asapcat/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
project(asapcat)
|
||||||
|
|
||||||
|
#set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_ENABLE_EXCEPTIONS}" )
|
||||||
|
set(AKONADI_PROTOCOLINTERNALS_LIBS ${akonadiprotocolinternals_LIB_DEPENDS} akonadiprotocolinternals)
|
||||||
|
|
||||||
|
set(asapcat_srcs
|
||||||
|
main.cpp
|
||||||
|
session.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(asapcat ${asapcat_srcs})
|
||||||
|
|
||||||
|
target_link_libraries(asapcat akonadi_shared ${QT_QTCORE_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${AKONADI_PROTOCOLINTERNALS_LIBS} ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||||
|
|
||||||
|
install(TARGETS asapcat DESTINATION ${BIN_INSTALL_DIR})
|
50
akonadi/asapcat/main.cpp
Normal file
50
akonadi/asapcat/main.cpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2013 by Volker Krause <vkrause@kde.org> *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Library General Public License as *
|
||||||
|
* published by the Free Software Foundation; either version 2 of the *
|
||||||
|
* License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public *
|
||||||
|
* License along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <session.h>
|
||||||
|
|
||||||
|
#include <shared/akapplication.h>
|
||||||
|
#include <shared/akstandarddirs.h>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
int main( int argc, char **argv )
|
||||||
|
{
|
||||||
|
AkCoreApplication app( argc, argv );
|
||||||
|
app.setDescription( QLatin1String( "Akonadi ASAP cat\n"
|
||||||
|
"This is a development tool, only use this if you know what you are doing.\n\n"
|
||||||
|
"Usage: asapcat [input]" ) );
|
||||||
|
|
||||||
|
boost::program_options::options_description options;
|
||||||
|
options.add_options()
|
||||||
|
( "input", boost::program_options::value<std::string>()->default_value( "-" ), "input to read commands from" );
|
||||||
|
app.addCommandLineOptions( options );
|
||||||
|
app.addPositionalCommandLineOption( "input", 1 );
|
||||||
|
|
||||||
|
app.parseCommandLine();
|
||||||
|
|
||||||
|
Session session( QString::fromStdString( app.commandLineArguments()["input"].as<std::string>() ) );
|
||||||
|
QObject::connect( &session, SIGNAL(disconnected()), QCoreApplication::instance(), SLOT(quit()) );
|
||||||
|
QMetaObject::invokeMethod( &session, "connectToHost", Qt::QueuedConnection );
|
||||||
|
|
||||||
|
const int result = app.exec();
|
||||||
|
session.printStats();
|
||||||
|
return result;
|
||||||
|
}
|
153
akonadi/asapcat/session.cpp
Normal file
153
akonadi/asapcat/session.cpp
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2013 by Volker Krause <vkrause@kde.org> *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Library General Public License as *
|
||||||
|
* published by the Free Software Foundation; either version 2 of the *
|
||||||
|
* License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public *
|
||||||
|
* License along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
|
#include <shared/akstandarddirs.h>
|
||||||
|
#include <shared/akdebug.h>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QSocketNotifier>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
Session::Session( const QString &input, QObject *parent )
|
||||||
|
: QObject( parent )
|
||||||
|
, m_input( 0 )
|
||||||
|
, m_session( 0 )
|
||||||
|
, m_notifier( 0 )
|
||||||
|
, m_receivedBytes( 0 )
|
||||||
|
, m_sentBytes( 0 )
|
||||||
|
{
|
||||||
|
QFile *file = new QFile( this );
|
||||||
|
if ( input != QLatin1String( "-" ) ) {
|
||||||
|
file->setFileName( input );
|
||||||
|
if ( !file->open( QFile::ReadOnly ) ) {
|
||||||
|
akFatal() << "Failed to open" << input;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ### does that work on Windows?
|
||||||
|
const int flags = fcntl( 0, F_GETFL );
|
||||||
|
fcntl( 0, F_SETFL, flags | O_NONBLOCK );
|
||||||
|
|
||||||
|
if ( !file->open( stdin, QFile::ReadOnly|QFile::Unbuffered ) ) {
|
||||||
|
akFatal() << "Failed to open stdin!";
|
||||||
|
}
|
||||||
|
m_notifier = new QSocketNotifier( 0, QSocketNotifier::Read, this );
|
||||||
|
connect( m_notifier, SIGNAL(activated(int)), SLOT(inputAvailable()) );
|
||||||
|
}
|
||||||
|
m_input = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
Session::~Session()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::connectToHost()
|
||||||
|
{
|
||||||
|
const QSettings connectionSettings( AkStandardDirs::connectionConfigFile(), QSettings::IniFormat );
|
||||||
|
|
||||||
|
QString serverAddress;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
serverAddress = connectionSettings.value( QLatin1String( "Data/NamedPipe" ), QString() ).toString();
|
||||||
|
#else
|
||||||
|
serverAddress = connectionSettings.value( QLatin1String( "Data/UnixPath" ), QString() ).toString();
|
||||||
|
#endif
|
||||||
|
if ( serverAddress.isEmpty() ) {
|
||||||
|
akFatal() << "Unable to determine server address.";
|
||||||
|
}
|
||||||
|
|
||||||
|
QLocalSocket *socket = new QLocalSocket( this );
|
||||||
|
connect( socket, SIGNAL(error(QLocalSocket::LocalSocketError)), SLOT(serverError(QLocalSocket::LocalSocketError)) );
|
||||||
|
connect( socket, SIGNAL(disconnected()), SLOT(serverDisconnected()) );
|
||||||
|
connect( socket, SIGNAL(readyRead()), SLOT(serverRead()) );
|
||||||
|
connect( socket, SIGNAL(connected()), SLOT(inputAvailable()) );
|
||||||
|
|
||||||
|
m_session = socket;
|
||||||
|
socket->connectToServer( serverAddress );
|
||||||
|
|
||||||
|
m_connectionTime.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::inputAvailable()
|
||||||
|
{
|
||||||
|
if ( !m_session->isOpen() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_notifier ) {
|
||||||
|
m_notifier->setEnabled( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_input->atEnd() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray buffer( 1024, Qt::Uninitialized );
|
||||||
|
qint64 readSize = 0;
|
||||||
|
|
||||||
|
while ( ( readSize = m_input->read( buffer.data(), buffer.size() ) ) > 0 ) {
|
||||||
|
m_session->write( buffer.constData(), readSize );
|
||||||
|
m_sentBytes += readSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_notifier ) {
|
||||||
|
m_notifier->setEnabled( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::serverDisconnected()
|
||||||
|
{
|
||||||
|
QCoreApplication::exit( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::serverError( QLocalSocket::LocalSocketError socketError )
|
||||||
|
{
|
||||||
|
if ( socketError == QLocalSocket::PeerClosedError ) {
|
||||||
|
QCoreApplication::exit( 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << qPrintable( m_session->errorString() );
|
||||||
|
QCoreApplication::exit( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::serverRead()
|
||||||
|
{
|
||||||
|
QByteArray buffer( 1024, Qt::Uninitialized );
|
||||||
|
qint64 readSize = 0;
|
||||||
|
|
||||||
|
while ( ( readSize = m_session->read( buffer.data(), buffer.size() ) ) > 0 ) {
|
||||||
|
write( 1, buffer.data(), readSize );
|
||||||
|
m_receivedBytes += readSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::printStats() const
|
||||||
|
{
|
||||||
|
std::cerr << "Connection time: " << m_connectionTime.elapsed() << " ms" << std::endl;
|
||||||
|
std::cerr << "Sent: " << m_sentBytes << " bytes" << std::endl;
|
||||||
|
std::cerr << "Received: " << m_receivedBytes << " bytes" << std::endl;
|
||||||
|
}
|
62
akonadi/asapcat/session.h
Normal file
62
akonadi/asapcat/session.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2013 by Volker Krause <vkrause@kde.org> *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Library General Public License as *
|
||||||
|
* published by the Free Software Foundation; either version 2 of the *
|
||||||
|
* License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public *
|
||||||
|
* License along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SESSION_H
|
||||||
|
#define SESSION_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
class QIODevice;
|
||||||
|
class QSocketNotifier;
|
||||||
|
|
||||||
|
/** ASAP CLI session. */
|
||||||
|
class Session : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Session( const QString &input, QObject *parent = 0 );
|
||||||
|
~Session();
|
||||||
|
|
||||||
|
void printStats() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void connectToHost();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void disconnected();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void inputAvailable();
|
||||||
|
void serverDisconnected();
|
||||||
|
void serverError( QLocalSocket::LocalSocketError socketError );
|
||||||
|
void serverRead();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QIODevice *m_input;
|
||||||
|
QIODevice *m_session;
|
||||||
|
QSocketNotifier *m_notifier;
|
||||||
|
|
||||||
|
QTime m_connectionTime;
|
||||||
|
qint64 m_receivedBytes;
|
||||||
|
qint64 m_sentBytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SESSION_H
|
4
akonadi/asapcat/tests/imap-4.10-sync.asap
Normal file
4
akonadi/asapcat/tests/imap-4.10-sync.asap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
1 LOGIN asapcat
|
||||||
|
2 UID SELECT SILENT 471
|
||||||
|
3 FETCH 1:* CACHEONLY EXTERNALPAYLOAD (UID REMOTEID REMOTEREVISION COLLECTIONID FLAGS SIZE)
|
||||||
|
4 LOGOUT
|
4
akonadi/asapcat/tests/imap-4.11-body-check.asap
Normal file
4
akonadi/asapcat/tests/imap-4.11-body-check.asap
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
1 LOGIN asapcat
|
||||||
|
2 UID SELECT SILENT 471
|
||||||
|
3 FETCH 1:* CACHEONLY CHECKCACHEDPARTSONLY EXTERNALPAYLOAD (UID REMOTEID REMOTEREVISION COLLECTIONID FLAGS SIZE PLD:RFC822)
|
||||||
|
4 LOGOUT
|
5
akonadi/asapcat/tests/kmail-4.10-folder-listing.asap
Normal file
5
akonadi/asapcat/tests/kmail-4.10-folder-listing.asap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
1 LOGIN asapcat
|
||||||
|
2 UID SELECT SILENT 471
|
||||||
|
3 FETCH 1:* IGNOREERRORS ANCESTORS INF EXTERNALPAYLOAD (UID REMOTEID REMOTEREVISION COLLECTIONID FLAGS SIZE DATETIME PLD:ENVELOPE)
|
||||||
|
4 LOGOUT
|
||||||
|
|
5
akonadi/asapcat/tests/kmail-4.11-folder-listing.asap
Normal file
5
akonadi/asapcat/tests/kmail-4.11-folder-listing.asap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
1 LOGIN asapcat
|
||||||
|
2 UID SELECT SILENT 471
|
||||||
|
3 FETCH 1:* IGNOREERRORS ANCESTORS INF EXTERNALPAYLOAD (UID REMOTEID REMOTEREVISION COLLECTIONID FLAGS SIZE PLD:ENVELOPE)
|
||||||
|
4 LOGOUT
|
||||||
|
|
5
akonadi/asapcat/tests/kmail-4.12-folder-listing.asap
Normal file
5
akonadi/asapcat/tests/kmail-4.12-folder-listing.asap
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
1 LOGIN asapcat
|
||||||
|
2 UID SELECT SILENT 496
|
||||||
|
3 FETCH 1:* IGNOREERRORS ANCESTORS INF EXTERNALPAYLOAD (UID COLLECTIONID FLAGS SIZE PLD:ENVELOPE)
|
||||||
|
4 LOGOUT
|
||||||
|
|
30
akonadi/cmake/modules/BasicFindPackageVersion.cmake.in
Normal file
30
akonadi/cmake/modules/BasicFindPackageVersion.cmake.in
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# This is a very basic file for the new style find_package() search mode,
|
||||||
|
# i.e. Config-mode. It is used by MACRO_WRITE_BASIC_CMAKE_VERSION_FILE() from
|
||||||
|
# MacroWriteBasicCMakeVersionFile.cmake.
|
||||||
|
# In this mode find_package() searches for a <package>Config.cmake
|
||||||
|
# file and an associated <package>Version.cmake file, which it loads to check
|
||||||
|
# the version number.
|
||||||
|
# This file can be used with configure_file() to generate such a file for a project
|
||||||
|
# with very basic logic.
|
||||||
|
# It sets PACKAGE_VERSION_EXACT if the current version string and the requested
|
||||||
|
# version string are exactly the same and it sets PACKAGE_VERSION_COMPATIBLE
|
||||||
|
# if the current version is >= requested version.
|
||||||
|
# If this is not good enough for your project, you need to write your own
|
||||||
|
# improved <package>Version.cmake file.
|
||||||
|
# This file requires the following three variables to be set:
|
||||||
|
# PROJECT_VERSION_MAJOR
|
||||||
|
# PROJECT_VERSION_MINOR
|
||||||
|
# PROJECT_VERSION_PATCH
|
||||||
|
|
||||||
|
|
||||||
|
set(PACKAGE_VERSION @PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@)
|
||||||
|
|
||||||
|
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||||
|
else("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||||
|
if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
|
||||||
|
set(PACKAGE_VERSION_EXACT TRUE)
|
||||||
|
endif( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
|
||||||
|
endif("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
|
||||||
|
|
22
akonadi/cmake/modules/COPYING-CMAKE-SCRIPTS
Normal file
22
akonadi/cmake/modules/COPYING-CMAKE-SCRIPTS
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. The name of the author may not be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
119
akonadi/cmake/modules/ECMQt4To5Porting.cmake
Normal file
119
akonadi/cmake/modules/ECMQt4To5Porting.cmake
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2005-2011 Kitware, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# * Neither the name of Kitware, Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived
|
||||||
|
# from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
|
# Portability helpers.
|
||||||
|
|
||||||
|
set(QT_QTGUI_LIBRARIES
|
||||||
|
${Qt5Gui_LIBRARIES}
|
||||||
|
${Qt5Widgets_LIBRARIES}
|
||||||
|
${Qt5PrintSupport_LIBRARIES}
|
||||||
|
${Qt5Svg_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(QT_INCLUDES
|
||||||
|
${Qt5Gui_INCLUDE_DIRS}
|
||||||
|
${Qt5Widgets_INCLUDE_DIRS}
|
||||||
|
${Qt5PrintSupport_INCLUDE_DIRS}
|
||||||
|
${Qt5Svg_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(_qt_modules
|
||||||
|
Core
|
||||||
|
Declarative
|
||||||
|
Widgets
|
||||||
|
Script
|
||||||
|
ScriptTools
|
||||||
|
DBus
|
||||||
|
Network
|
||||||
|
Test
|
||||||
|
Designer
|
||||||
|
Concurrent
|
||||||
|
Xml
|
||||||
|
UiTools
|
||||||
|
WebKit
|
||||||
|
Sql
|
||||||
|
OpenGL
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach(_module ${_qt_modules})
|
||||||
|
string(TOUPPER ${_module} _module_upper)
|
||||||
|
set(QT_QT${_module_upper}_LIBRARIES ${Qt5${_module}_LIBRARIES})
|
||||||
|
set(QT_QT${_module_upper}_LIBRARY ${QT_QT${_module_upper}_LIBRARIES})
|
||||||
|
list(APPEND QT_INCLUDES ${Qt5${_module}_INCLUDE_DIRS})
|
||||||
|
set(QT_QT${_module_upper}_FOUND ${Qt5${_module}_FOUND})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
get_target_property(QT_QMAKE_EXECUTABLE Qt5::qmake LOCATION)
|
||||||
|
get_target_property(QT_RCC_EXECUTABLE Qt5::rcc LOCATION)
|
||||||
|
if (TARGET Qt5::uic)
|
||||||
|
get_target_property(QT_UIC_EXECUTABLE Qt5::uic LOCATION)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (TARGET Qt5::qdbuscpp2xml)
|
||||||
|
get_target_property(QT_QDBUSCPP2XML_EXECUTABLE Qt5::qdbuscpp2xml LOCATION)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (TARGET Qt5::qdbusxml2cpp)
|
||||||
|
get_target_property(QT_QDBUSXML2CPP_EXECUTABLE Qt5::qdbusxml2cpp LOCATION)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
macro(qt4_wrap_ui)
|
||||||
|
qt5_wrap_ui(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qt4_wrap_cpp)
|
||||||
|
qt5_wrap_cpp(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qt4_generate_moc)
|
||||||
|
qt5_generate_moc(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qt4_add_dbus_adaptor)
|
||||||
|
qt5_add_dbus_adaptor(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qt4_add_dbus_interfaces)
|
||||||
|
qt5_add_dbus_interfaces(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qt4_add_dbus_interface)
|
||||||
|
qt5_add_dbus_interface(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qt4_generate_dbus_interface)
|
||||||
|
qt5_generate_dbus_interface(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qt4_add_resources)
|
||||||
|
qt5_add_resources(${ARGN})
|
||||||
|
endmacro()
|
84
akonadi/cmake/modules/FindBacktrace.cmake
Normal file
84
akonadi/cmake/modules/FindBacktrace.cmake
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
# - Find provider for backtrace(3)
|
||||||
|
# Checks if OS supports backtrace(3) via either libc or custom library.
|
||||||
|
# This module defines the following variables:
|
||||||
|
# Backtrace_HEADER - The header file needed for backtrace(3). Cached.
|
||||||
|
# Could be forcibly set by user.
|
||||||
|
# Backtrace_INCLUDE_DIRS - The include directories needed to use backtrace(3) header.
|
||||||
|
# Backtrace_LIBRARIES - The libraries (linker flags) needed to use backtrace(3), if any.
|
||||||
|
# Backtrace_FOUND - Is set if and only if backtrace(3) support detected.
|
||||||
|
#
|
||||||
|
# The following cache variables are also available to set or use:
|
||||||
|
# Backtrace_LIBRARY - The external library providing backtrace, if any.
|
||||||
|
# Backtrace_INCLUDE_DIR - The directory holding the backtrace(3) header.
|
||||||
|
#
|
||||||
|
# Typical usage is to generate of header file using configure_file() with the
|
||||||
|
# contents like the following:
|
||||||
|
# #cmakedefine01 Backtrace_FOUND
|
||||||
|
# #if Backtrace_FOUND
|
||||||
|
# # include <${Backtrace_HEADER}>
|
||||||
|
# #endif
|
||||||
|
# And then reference that generated header file in actual source.
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright (c) 2013, Vadim Zhukov <persgray@gmail.com>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
include(CMakePushCheckState)
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
|
# List of variables to be provided to find_package_handle_standard_args()
|
||||||
|
set(_Backtrace_STD_ARGS Backtrace_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if(Backtrace_HEADER)
|
||||||
|
set(_Backtrace_HEADER_TRY "${Backtrace_HEADER}")
|
||||||
|
else(Backtrace_HEADER)
|
||||||
|
set(_Backtrace_HEADER_TRY "execinfo.h")
|
||||||
|
endif(Backtrace_HEADER)
|
||||||
|
|
||||||
|
find_path(Backtrace_INCLUDE_DIR "${_Backtrace_HEADER_TRY}")
|
||||||
|
set(Backtrace_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
|
||||||
|
|
||||||
|
# First, check if we already have backtrace(), e.g., in libc
|
||||||
|
cmake_push_check_state(RESET)
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${Backtrace_INCLUDE_DIRS})
|
||||||
|
check_symbol_exists("backtrace" "${_Backtrace_HEADER_TRY}" _Backtrace_SYM_FOUND)
|
||||||
|
cmake_pop_check_state()
|
||||||
|
|
||||||
|
if(_Backtrace_SYM_FOUND)
|
||||||
|
set(Backtrace_LIBRARY)
|
||||||
|
if(NOT Backtrace_FIND_QUIETLY)
|
||||||
|
message(STATUS "backtrace facility detected in default set of libraries")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# Check for external library, for non-glibc systems
|
||||||
|
if(Backtrace_INCLUDE_DIR)
|
||||||
|
# OpenBSD has libbacktrace renamed to libexecinfo
|
||||||
|
find_library(Backtrace_LIBRARY "execinfo")
|
||||||
|
elseif() # respect user wishes
|
||||||
|
set(_Backtrace_HEADER_TRY "backtrace.h")
|
||||||
|
find_path(Backtrace_INCLUDE_DIR ${_Backtrace_HEADER_TRY})
|
||||||
|
find_library(Backtrace_LIBRARY "backtrace")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Prepend list with library path as it's more common practice
|
||||||
|
set(_Backtrace_STD_ARGS Backtrace_LIBRARY ${_Backtrace_STD_ARGS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(Backtrace_LIBRARIES ${Backtrace_LIBRARY})
|
||||||
|
set(Backtrace_HEADER "${_Backtrace_HEADER_TRY}" CACHE STRING "Header providing backtrace(3) facility")
|
||||||
|
|
||||||
|
find_package_handle_standard_args(Backtrace FOUND_VAR Backtrace_FOUND REQUIRED_VARS ${_Backtrace_STD_ARGS})
|
||||||
|
mark_as_advanced(Backtrace_HEADER Backtrace_INCLUDE_DIR Backtrace_LIBRARY)
|
113
akonadi/cmake/modules/FindLibraryWithDebug.cmake
Normal file
113
akonadi/cmake/modules/FindLibraryWithDebug.cmake
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
#
|
||||||
|
# FIND_LIBRARY_WITH_DEBUG
|
||||||
|
# -> enhanced FIND_LIBRARY to allow the search for an
|
||||||
|
# optional debug library with a WIN32_DEBUG_POSTFIX similar
|
||||||
|
# to CMAKE_DEBUG_POSTFIX when creating a shared lib
|
||||||
|
# it has to be the second and third argument
|
||||||
|
|
||||||
|
# Copyright (c) 2007, Christian Ehrlicher, <ch.ehrlicher@gmx.de>
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
MACRO(FIND_LIBRARY_WITH_DEBUG var_name win32_dbg_postfix_name dgb_postfix libname)
|
||||||
|
|
||||||
|
IF(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX")
|
||||||
|
|
||||||
|
# no WIN32_DEBUG_POSTFIX -> simply pass all arguments to FIND_LIBRARY
|
||||||
|
FIND_LIBRARY(${var_name}
|
||||||
|
${win32_dbg_postfix_name}
|
||||||
|
${dgb_postfix}
|
||||||
|
${libname}
|
||||||
|
${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
|
ELSE(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX")
|
||||||
|
|
||||||
|
IF(NOT WIN32)
|
||||||
|
# on non-win32 we don't need to take care about WIN32_DEBUG_POSTFIX
|
||||||
|
|
||||||
|
FIND_LIBRARY(${var_name} ${libname} ${ARGN})
|
||||||
|
|
||||||
|
ELSE(NOT WIN32)
|
||||||
|
|
||||||
|
# 1. get all possible libnames
|
||||||
|
SET(args ${ARGN})
|
||||||
|
SET(newargs "")
|
||||||
|
SET(libnames_release "")
|
||||||
|
SET(libnames_debug "")
|
||||||
|
|
||||||
|
LIST(LENGTH args listCount)
|
||||||
|
|
||||||
|
IF("${libname}" STREQUAL "NAMES")
|
||||||
|
SET(append_rest 0)
|
||||||
|
LIST(APPEND args " ")
|
||||||
|
|
||||||
|
FOREACH(i RANGE ${listCount})
|
||||||
|
LIST(GET args ${i} val)
|
||||||
|
|
||||||
|
IF(append_rest)
|
||||||
|
LIST(APPEND newargs ${val})
|
||||||
|
ELSE(append_rest)
|
||||||
|
IF("${val}" STREQUAL "PATHS")
|
||||||
|
LIST(APPEND newargs ${val})
|
||||||
|
SET(append_rest 1)
|
||||||
|
ELSE("${val}" STREQUAL "PATHS")
|
||||||
|
LIST(APPEND libnames_release "${val}")
|
||||||
|
LIST(APPEND libnames_debug "${val}${dgb_postfix}")
|
||||||
|
ENDIF("${val}" STREQUAL "PATHS")
|
||||||
|
ENDIF(append_rest)
|
||||||
|
|
||||||
|
ENDFOREACH(i)
|
||||||
|
|
||||||
|
ELSE("${libname}" STREQUAL "NAMES")
|
||||||
|
|
||||||
|
# just one name
|
||||||
|
LIST(APPEND libnames_release "${libname}")
|
||||||
|
LIST(APPEND libnames_debug "${libname}${dgb_postfix}")
|
||||||
|
|
||||||
|
SET(newargs ${args})
|
||||||
|
|
||||||
|
ENDIF("${libname}" STREQUAL "NAMES")
|
||||||
|
|
||||||
|
# search the release lib
|
||||||
|
FIND_LIBRARY(${var_name}_RELEASE
|
||||||
|
NAMES ${libnames_release}
|
||||||
|
${newargs}
|
||||||
|
)
|
||||||
|
|
||||||
|
# search the debug lib
|
||||||
|
FIND_LIBRARY(${var_name}_DEBUG
|
||||||
|
NAMES ${libnames_debug}
|
||||||
|
${newargs}
|
||||||
|
)
|
||||||
|
|
||||||
|
IF(${var_name}_RELEASE AND ${var_name}_DEBUG)
|
||||||
|
|
||||||
|
# both libs found
|
||||||
|
SET(${var_name} optimized ${${var_name}_RELEASE}
|
||||||
|
debug ${${var_name}_DEBUG})
|
||||||
|
|
||||||
|
ELSE(${var_name}_RELEASE AND ${var_name}_DEBUG)
|
||||||
|
|
||||||
|
IF(${var_name}_RELEASE)
|
||||||
|
|
||||||
|
# only release found
|
||||||
|
SET(${var_name} ${${var_name}_RELEASE})
|
||||||
|
|
||||||
|
ELSE(${var_name}_RELEASE)
|
||||||
|
|
||||||
|
# only debug (or nothing) found
|
||||||
|
SET(${var_name} ${${var_name}_DEBUG})
|
||||||
|
|
||||||
|
ENDIF(${var_name}_RELEASE)
|
||||||
|
|
||||||
|
ENDIF(${var_name}_RELEASE AND ${var_name}_DEBUG)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(${var_name}_RELEASE)
|
||||||
|
MARK_AS_ADVANCED(${var_name}_DEBUG)
|
||||||
|
|
||||||
|
ENDIF(NOT WIN32)
|
||||||
|
|
||||||
|
ENDIF(NOT "${win32_dbg_postfix_name}" STREQUAL "WIN32_DEBUG_POSTFIX")
|
||||||
|
|
||||||
|
ENDMACRO(FIND_LIBRARY_WITH_DEBUG)
|
67
akonadi/cmake/modules/FindSharedMimeInfo.cmake
Normal file
67
akonadi/cmake/modules/FindSharedMimeInfo.cmake
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# - Try to find the shared-mime-info package
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# SharedMimeInfo_FOUND - system has the shared-mime-info package
|
||||||
|
# UPDATE_MIME_DATABASE_EXECUTABLE - the update-mime-database executable
|
||||||
|
|
||||||
|
# Copyright (c) 2007, Pino Toscano, <toscano.pino@tiscali.it>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
# the minimum version of shared-mime-database we require
|
||||||
|
if (NOT SHARED_MIME_INFO_MINIMUM_VERSION)
|
||||||
|
set(SHARED_MIME_INFO_MINIMUM_VERSION "0.18")
|
||||||
|
endif (NOT SHARED_MIME_INFO_MINIMUM_VERSION)
|
||||||
|
|
||||||
|
if (UPDATE_MIME_DATABASE_EXECUTABLE)
|
||||||
|
|
||||||
|
# in cache already
|
||||||
|
set(SharedMimeInfo_FOUND TRUE)
|
||||||
|
|
||||||
|
else (UPDATE_MIME_DATABASE_EXECUTABLE)
|
||||||
|
|
||||||
|
include (MacroEnsureVersion)
|
||||||
|
|
||||||
|
find_program (UPDATE_MIME_DATABASE_EXECUTABLE NAMES update-mime-database)
|
||||||
|
|
||||||
|
if (UPDATE_MIME_DATABASE_EXECUTABLE)
|
||||||
|
|
||||||
|
exec_program (${UPDATE_MIME_DATABASE_EXECUTABLE} ARGS -v RETURN_VALUE _null OUTPUT_VARIABLE _smiVersionRaw)
|
||||||
|
|
||||||
|
string(REGEX REPLACE "update-mime-database \\([a-zA-Z\\-]+\\) ([0-9]\\.[0-9]+).*"
|
||||||
|
"\\1" smiVersion "${_smiVersionRaw}")
|
||||||
|
set (SharedMimeInfo_FOUND TRUE)
|
||||||
|
endif (UPDATE_MIME_DATABASE_EXECUTABLE)
|
||||||
|
|
||||||
|
if (SharedMimeInfo_FOUND)
|
||||||
|
if (NOT SharedMimeInfo_FIND_QUIETLY)
|
||||||
|
message(STATUS "Found shared-mime-info version: ${smiVersion}")
|
||||||
|
macro_ensure_version(${SHARED_MIME_INFO_MINIMUM_VERSION} ${smiVersion} _smiVersion_OK)
|
||||||
|
if (NOT _smiVersion_OK)
|
||||||
|
message(FATAL_ERROR "The found version of shared-mime-info (${smiVersion}) is below the minimum required (${SHARED_MIME_INFO_MINIMUM_VERSION})")
|
||||||
|
endif (NOT _smiVersion_OK)
|
||||||
|
|
||||||
|
endif (NOT SharedMimeInfo_FIND_QUIETLY)
|
||||||
|
else (SharedMimeInfo_FOUND)
|
||||||
|
if (SharedMimeInfo_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "Could NOT find shared-mime-info. See http://freedesktop.org/wiki/Software/shared-mime-info.")
|
||||||
|
endif (SharedMimeInfo_FIND_REQUIRED)
|
||||||
|
endif (SharedMimeInfo_FOUND)
|
||||||
|
|
||||||
|
endif (UPDATE_MIME_DATABASE_EXECUTABLE)
|
||||||
|
|
||||||
|
macro(UPDATE_XDG_MIMETYPES _path)
|
||||||
|
get_filename_component(_xdgmimeDir "${_path}" NAME)
|
||||||
|
if("${_xdgmimeDir}" STREQUAL packages )
|
||||||
|
get_filename_component(_xdgmimeDir "${_path}" PATH)
|
||||||
|
else("${_xdgmimeDir}" STREQUAL packages )
|
||||||
|
set(_xdgmimeDir "${_path}")
|
||||||
|
endif("${_xdgmimeDir}" STREQUAL packages )
|
||||||
|
install(CODE "
|
||||||
|
set(DESTDIR_VALUE \"\$ENV{DESTDIR}\")
|
||||||
|
if (NOT DESTDIR_VALUE)
|
||||||
|
execute_process(COMMAND ${UPDATE_MIME_DATABASE_EXECUTABLE} ${_xdgmimeDir})
|
||||||
|
endif (NOT DESTDIR_VALUE)
|
||||||
|
")
|
||||||
|
endmacro (UPDATE_XDG_MIMETYPES)
|
209
akonadi/cmake/modules/FindSoprano.cmake
Normal file
209
akonadi/cmake/modules/FindSoprano.cmake
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
#
|
||||||
|
# Find an installation of Soprano
|
||||||
|
#
|
||||||
|
# Sets the following variables:
|
||||||
|
# Soprano_FOUND - true is Soprano has been found
|
||||||
|
# SOPRANO_INCLUDE_DIR - The include directory
|
||||||
|
# SOPRANO_LIBRARIES - The Soprano core library to link to (libsoprano)
|
||||||
|
# SOPRANO_INDEX_LIBRARIES - The Soprano index library (libsopranoindex)
|
||||||
|
# SOPRANO_CLIENT_LIBRARIES - The Soprano client library (libsopranoclient)
|
||||||
|
# SOPRANO_SERVER_LIBRARIES - The Soprano server library (libsopranoserver)
|
||||||
|
# SOPRANO_VERSION - The Soprano version (string value)
|
||||||
|
#
|
||||||
|
# SOPRANO_PLUGIN_NQUADPARSER_FOUND - true if the nquadparser plugin is found
|
||||||
|
# SOPRANO_PLUGIN_NQUADSERIALIZER_FOUND - true if the nquadserializer plugin is found
|
||||||
|
# SOPRANO_PLUGIN_RAPTORPARSER_FOUND - true if the raptorparser plugin is found
|
||||||
|
# SOPRANO_PLUGIN_RAPTORSERIALIZER_FOUND - true if the raptorserializer plugin is found
|
||||||
|
# SOPRANO_PLUGIN_REDLANDBACKEND_FOUND - true if the redlandbackend plugin is found
|
||||||
|
# SOPRANO_PLUGIN_SESAME2BACKEND_FOUND - true if the sesame2backend plugin is found
|
||||||
|
# SOPRANO_PLUGIN_VIRTUOSOBACKEND_FOUND - true if the virtuosobackend plugin is found
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
# Set SOPRANO_MIN_VERSION to set the minimum required Soprano version (default: 1.99)
|
||||||
|
#
|
||||||
|
|
||||||
|
# Copyright (c) 2008, Sebastian Trueg, <sebastian@trueg.de>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
|
||||||
|
include(FindLibraryWithDebug)
|
||||||
|
|
||||||
|
# have packageconfig set variables to find Soprano:
|
||||||
|
# package config dirs are used as secondary search paths after install_dir
|
||||||
|
find_package(PkgConfig)
|
||||||
|
if (PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(Soprano_PKGCONF soprano)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_path(SOPRANO_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
soprano/soprano.h
|
||||||
|
HINTS
|
||||||
|
${INCLUDE_INSTALL_DIR}
|
||||||
|
${Soprano_PKGCONF_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library_with_debug(SOPRANO_INDEX_LIBRARIES
|
||||||
|
WIN32_DEBUG_POSTFIX d
|
||||||
|
NAMES
|
||||||
|
sopranoindex
|
||||||
|
HINTS
|
||||||
|
${LIB_INSTALL_DIR}
|
||||||
|
${Soprano_PKGCONF_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library_with_debug(SOPRANO_CLIENT_LIBRARIES
|
||||||
|
WIN32_DEBUG_POSTFIX d
|
||||||
|
NAMES
|
||||||
|
sopranoclient
|
||||||
|
HINTS
|
||||||
|
${LIB_INSTALL_DIR}
|
||||||
|
${Soprano_PKGCONF_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library_with_debug(SOPRANO_LIBRARIES
|
||||||
|
WIN32_DEBUG_POSTFIX d
|
||||||
|
NAMES soprano
|
||||||
|
HINTS
|
||||||
|
${LIB_INSTALL_DIR}
|
||||||
|
${Soprano_PKGCONF_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library_with_debug(SOPRANO_SERVER_LIBRARIES
|
||||||
|
WIN32_DEBUG_POSTFIX d
|
||||||
|
NAMES
|
||||||
|
sopranoserver
|
||||||
|
HINTS
|
||||||
|
${LIB_INSTALL_DIR}
|
||||||
|
${Soprano_PKGCONF_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
# check for all the libs as required to make sure that we do not try to compile with an old version
|
||||||
|
|
||||||
|
if(SOPRANO_INCLUDE_DIR AND SOPRANO_LIBRARIES)
|
||||||
|
set(Soprano_FOUND TRUE)
|
||||||
|
endif(SOPRANO_INCLUDE_DIR AND SOPRANO_LIBRARIES)
|
||||||
|
|
||||||
|
if(Soprano_FOUND AND SOPRANO_INDEX_LIBRARIES)
|
||||||
|
set(SopranoIndex_FOUND TRUE)
|
||||||
|
endif(Soprano_FOUND AND SOPRANO_INDEX_LIBRARIES)
|
||||||
|
|
||||||
|
if(Soprano_FOUND AND SOPRANO_CLIENT_LIBRARIES)
|
||||||
|
set(SopranoClient_FOUND TRUE)
|
||||||
|
endif(Soprano_FOUND AND SOPRANO_CLIENT_LIBRARIES)
|
||||||
|
|
||||||
|
if(Soprano_FOUND AND SOPRANO_SERVER_LIBRARIES)
|
||||||
|
set(SopranoServer_FOUND TRUE)
|
||||||
|
endif(Soprano_FOUND AND SOPRANO_SERVER_LIBRARIES)
|
||||||
|
|
||||||
|
# check Soprano version
|
||||||
|
|
||||||
|
# We set a default for the minimum required version to be backwards compatible
|
||||||
|
if(NOT SOPRANO_MIN_VERSION)
|
||||||
|
set(SOPRANO_MIN_VERSION "1.99")
|
||||||
|
endif(NOT SOPRANO_MIN_VERSION)
|
||||||
|
|
||||||
|
if(Soprano_FOUND)
|
||||||
|
file(READ ${SOPRANO_INCLUDE_DIR}/soprano/version.h SOPRANO_VERSION_CONTENT)
|
||||||
|
string(REGEX MATCH "SOPRANO_VERSION_STRING \".*\"\n" SOPRANO_VERSION_MATCH ${SOPRANO_VERSION_CONTENT})
|
||||||
|
if(SOPRANO_VERSION_MATCH)
|
||||||
|
string(REGEX REPLACE "SOPRANO_VERSION_STRING \"(.*)\"\n" "\\1" SOPRANO_VERSION ${SOPRANO_VERSION_MATCH})
|
||||||
|
if(SOPRANO_VERSION STRLESS "${SOPRANO_MIN_VERSION}")
|
||||||
|
set(Soprano_FOUND FALSE)
|
||||||
|
if(Soprano_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "Soprano version ${SOPRANO_VERSION} is too old. Please install ${SOPRANO_MIN_VERSION} or newer")
|
||||||
|
else(Soprano_FIND_REQUIRED)
|
||||||
|
message(STATUS "Soprano version ${SOPRANO_VERSION} is too old. Please install ${SOPRANO_MIN_VERSION} or newer")
|
||||||
|
endif(Soprano_FIND_REQUIRED)
|
||||||
|
endif(SOPRANO_VERSION STRLESS "${SOPRANO_MIN_VERSION}")
|
||||||
|
endif(SOPRANO_VERSION_MATCH)
|
||||||
|
endif(Soprano_FOUND)
|
||||||
|
|
||||||
|
|
||||||
|
#look for parser plugins
|
||||||
|
if(Soprano_FOUND)
|
||||||
|
find_path(SOPRANO_PLUGIN_DIR
|
||||||
|
NAMES
|
||||||
|
soprano/plugins
|
||||||
|
PATHS
|
||||||
|
${SOPRANO_INCLUDE_DIR}/../share
|
||||||
|
${SHARE_INSTALL_PREFIX}
|
||||||
|
/usr/share
|
||||||
|
/usr/local/share
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
NO_SYSTEM_ENVIRONMENT_PATH
|
||||||
|
)
|
||||||
|
set(SOPRANO_PLUGIN_DIR "${SOPRANO_PLUGIN_DIR}/soprano/plugins")
|
||||||
|
|
||||||
|
if(EXISTS ${SOPRANO_PLUGIN_DIR}/nquadparser.desktop)
|
||||||
|
set(SOPRANO_PLUGIN_NQUADPARSER_FOUND TRUE)
|
||||||
|
set(_plugins "${_plugins} nquadparser")
|
||||||
|
endif(EXISTS ${SOPRANO_PLUGIN_DIR}/nquadparser.desktop)
|
||||||
|
|
||||||
|
if(EXISTS ${SOPRANO_PLUGIN_DIR}/nquadserializer.desktop)
|
||||||
|
set(SOPRANO_PLUGIN_NQUADSERIALIZER_FOUND TRUE)
|
||||||
|
set(_plugins "${_plugins} nquadserializer")
|
||||||
|
endif(EXISTS ${SOPRANO_PLUGIN_DIR}/nquadserializer.desktop)
|
||||||
|
|
||||||
|
if(EXISTS ${SOPRANO_PLUGIN_DIR}/raptorparser.desktop)
|
||||||
|
set(SOPRANO_PLUGIN_RAPTORPARSER_FOUND TRUE)
|
||||||
|
set(_plugins "${_plugins} raptorparser")
|
||||||
|
endif(EXISTS ${SOPRANO_PLUGIN_DIR}/raptorparser.desktop)
|
||||||
|
|
||||||
|
if(EXISTS ${SOPRANO_PLUGIN_DIR}/raptorserializer.desktop)
|
||||||
|
set(SOPRANO_PLUGIN_RAPTORSERIALIZER_FOUND TRUE)
|
||||||
|
set(_plugins "${_plugins} raptorserializer")
|
||||||
|
endif(EXISTS ${SOPRANO_PLUGIN_DIR}/raptorserializer.desktop)
|
||||||
|
|
||||||
|
if(EXISTS ${SOPRANO_PLUGIN_DIR}/redlandbackend.desktop)
|
||||||
|
set(SOPRANO_PLUGIN_REDLANDBACKEND_FOUND TRUE)
|
||||||
|
set(_plugins "${_plugins} redlandbackend")
|
||||||
|
endif(EXISTS ${SOPRANO_PLUGIN_DIR}/redlandbackend.desktop)
|
||||||
|
|
||||||
|
if(EXISTS ${SOPRANO_PLUGIN_DIR}/sesame2backend.desktop)
|
||||||
|
set(SOPRANO_PLUGIN_SESAME2BACKEND_FOUND TRUE)
|
||||||
|
set(_plugins "${_plugins} sesame2backend")
|
||||||
|
endif(EXISTS ${SOPRANO_PLUGIN_DIR}/sesame2backend.desktop)
|
||||||
|
|
||||||
|
if(EXISTS ${SOPRANO_PLUGIN_DIR}/virtuosobackend.desktop)
|
||||||
|
set(SOPRANO_PLUGIN_VIRTUOSOBACKEND_FOUND TRUE)
|
||||||
|
set(_plugins "${_plugins} virtuosobackend")
|
||||||
|
endif(EXISTS ${SOPRANO_PLUGIN_DIR}/virtuosobackend.desktop)
|
||||||
|
|
||||||
|
endif(Soprano_FOUND)
|
||||||
|
|
||||||
|
if(Soprano_FOUND)
|
||||||
|
if(NOT Soprano_FIND_QUIETLY)
|
||||||
|
message(STATUS "Found Soprano version ${SOPRANO_VERSION}: ${SOPRANO_LIBRARIES}")
|
||||||
|
message(STATUS "Found Soprano includes: ${SOPRANO_INCLUDE_DIR}")
|
||||||
|
message(STATUS "Found Soprano Index: ${SOPRANO_INDEX_LIBRARIES}")
|
||||||
|
message(STATUS "Found Soprano Client: ${SOPRANO_CLIENT_LIBRARIES}")
|
||||||
|
message(STATUS "Found Soprano Plugin Dir: ${SOPRANO_PLUGIN_DIR}")
|
||||||
|
message(STATUS "Found Soprano Plugins:${_plugins}")
|
||||||
|
endif(NOT Soprano_FIND_QUIETLY)
|
||||||
|
else(Soprano_FOUND)
|
||||||
|
if(Soprano_FIND_REQUIRED)
|
||||||
|
if(NOT SOPRANO_INCLUDE_DIR)
|
||||||
|
message(FATAL_ERROR "Could not find Soprano includes.")
|
||||||
|
endif(NOT SOPRANO_INCLUDE_DIR)
|
||||||
|
if(NOT SOPRANO_LIBRARIES)
|
||||||
|
message(FATAL_ERROR "Could not find Soprano library.")
|
||||||
|
endif(NOT SOPRANO_LIBRARIES)
|
||||||
|
else(Soprano_FIND_REQUIRED)
|
||||||
|
if(NOT SOPRANO_INCLUDE_DIR)
|
||||||
|
message(STATUS "Could not find Soprano includes.")
|
||||||
|
endif(NOT SOPRANO_INCLUDE_DIR)
|
||||||
|
if(NOT SOPRANO_LIBRARIES)
|
||||||
|
message(STATUS "Could not find Soprano library.")
|
||||||
|
endif(NOT SOPRANO_LIBRARIES)
|
||||||
|
endif(Soprano_FIND_REQUIRED)
|
||||||
|
endif(Soprano_FOUND)
|
||||||
|
|
||||||
|
mark_as_advanced(SOPRANO_CLIENT_LIBRARIES
|
||||||
|
SOPRANO_INDEX_LIBRARIES
|
||||||
|
SOPRANO_LIBRARIES
|
||||||
|
SOPRANO_SERVER_LIBRARIES
|
||||||
|
SOPRANO_INCLUDE_DIR
|
||||||
|
SOPRANO_PLUGIN_DIR)
|
113
akonadi/cmake/modules/FindSqlite.cmake
Normal file
113
akonadi/cmake/modules/FindSqlite.cmake
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
# - Try to find Sqlite
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# SQLITE_FOUND - system has Sqlite
|
||||||
|
# SQLITE_INCLUDE_DIR - the Sqlite include directory
|
||||||
|
# SQLITE_LIBRARIES - Link these to use Sqlite
|
||||||
|
# SQLITE_MIN_VERSION - The minimum SQLite version
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008, Gilles Caulier, <caulier.gilles@gmail.com>
|
||||||
|
# Copyright (c) 2010, Christophe Giboudeaux, <cgiboudeaux@gmail.com>
|
||||||
|
# Copyright (c) 2014, Daniel Vrátil <dvratil@redhat.com>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
if(NOT SQLITE_MIN_VERSION)
|
||||||
|
set(SQLITE_MIN_VERSION "3.6.16")
|
||||||
|
endif(NOT SQLITE_MIN_VERSION)
|
||||||
|
|
||||||
|
if ( SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES )
|
||||||
|
# in cache already
|
||||||
|
SET(Sqlite_FIND_QUIETLY TRUE)
|
||||||
|
endif ( SQLITE_INCLUDE_DIR AND SQLITE_LIBRARIES )
|
||||||
|
|
||||||
|
# use pkg-config to get the directories and then use these values
|
||||||
|
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||||
|
if( NOT WIN32 )
|
||||||
|
find_package(PkgConfig)
|
||||||
|
|
||||||
|
pkg_check_modules(PC_SQLITE sqlite3)
|
||||||
|
|
||||||
|
set(SQLITE_DEFINITIONS ${PC_SQLITE_CFLAGS_OTHER})
|
||||||
|
endif( NOT WIN32 )
|
||||||
|
|
||||||
|
if(PC_SQLITE_FOUND)
|
||||||
|
find_path(SQLITE_INCLUDE_DIR
|
||||||
|
NAMES sqlite3.h
|
||||||
|
PATHS ${PC_SQLITE_INCLUDEDIR}
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(SQLITE_LIBRARIES
|
||||||
|
NAMES sqlite3
|
||||||
|
PATHS ${PC_SQLITE_LIBDIR}
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
else(PC_SQLITE_FOUND)
|
||||||
|
find_path(SQLITE_INCLUDE_DIR
|
||||||
|
NAMES sqlite3.h
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(SQLITE_LIBRARIES
|
||||||
|
NAMES sqlite3
|
||||||
|
)
|
||||||
|
endif(PC_SQLITE_FOUND)
|
||||||
|
|
||||||
|
if( UNIX )
|
||||||
|
find_file(SQLITE_STATIC_LIBRARIES
|
||||||
|
libsqlite3.a
|
||||||
|
${PC_SQLITE_LIBDIR}
|
||||||
|
)
|
||||||
|
else( UNIX )
|
||||||
|
# todo find static libs for other systems
|
||||||
|
# fallback to standard libs
|
||||||
|
set( SQLITE_STATIC_LIBRARIES ${SQLITE_LIBRARIES} )
|
||||||
|
endif( UNIX )
|
||||||
|
|
||||||
|
if(EXISTS ${SQLITE_INCLUDE_DIR}/sqlite3.h)
|
||||||
|
file(READ ${SQLITE_INCLUDE_DIR}/sqlite3.h SQLITE3_H_CONTENT)
|
||||||
|
string(REGEX MATCH "SQLITE_VERSION[ ]*\"[0-9.]*\"\n" SQLITE_VERSION_MATCH "${SQLITE3_H_CONTENT}")
|
||||||
|
|
||||||
|
if(SQLITE_VERSION_MATCH)
|
||||||
|
string(REGEX REPLACE ".*SQLITE_VERSION[ ]*\"(.*)\"\n" "\\1" SQLITE_VERSION ${SQLITE_VERSION_MATCH})
|
||||||
|
|
||||||
|
if(SQLITE_VERSION VERSION_LESS "${SQLITE_MIN_VERSION}")
|
||||||
|
message(STATUS "Sqlite ${SQLITE_VERSION} was found, but at least version ${SQLITE_MIN_VERSION} is required")
|
||||||
|
set(SQLITE_VERSION_OK FALSE)
|
||||||
|
else(SQLITE_VERSION VERSION_LESS "${SQLITE_MIN_VERSION}")
|
||||||
|
set(SQLITE_VERSION_OK TRUE)
|
||||||
|
endif(SQLITE_VERSION VERSION_LESS "${SQLITE_MIN_VERSION}")
|
||||||
|
|
||||||
|
endif(SQLITE_VERSION_MATCH)
|
||||||
|
|
||||||
|
if (SQLITE_VERSION_OK)
|
||||||
|
file(WRITE ${CMAKE_BINARY_DIR}/sqlite_check_unlock_notify.cpp
|
||||||
|
"#include <sqlite3.h>
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
return sqlite3_unlock_notify(0, 0, 0);
|
||||||
|
}")
|
||||||
|
try_compile(SQLITE_HAS_UNLOCK_NOTIFY
|
||||||
|
${CMAKE_BINARY_DIR}/sqlite_check_unlock_notify
|
||||||
|
${CMAKE_BINARY_DIR}/sqlite_check_unlock_notify.cpp
|
||||||
|
LINK_LIBRARIES ${SQLITE_LIBRARIES}
|
||||||
|
CMAKE_FLAGS INCLUDE_DIRECTORIES ${SQLITE_INCLUDE_DIR})
|
||||||
|
if (NOT SQLITE_HAS_UNLOCK_NOTIFY)
|
||||||
|
message(STATUS "Sqlite ${SQLITE_VERSION} was found, but it is not compiled with -DSQLITE_ENABLE_UNLOCK_NOTIFY")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args( Sqlite DEFAULT_MSG
|
||||||
|
SQLITE_INCLUDE_DIR
|
||||||
|
SQLITE_LIBRARIES
|
||||||
|
SQLITE_VERSION_OK
|
||||||
|
SQLITE_HAS_UNLOCK_NOTIFY)
|
||||||
|
|
||||||
|
# show the SQLITE_INCLUDE_DIR and SQLITE_LIBRARIES variables only in the advanced view
|
||||||
|
mark_as_advanced( SQLITE_INCLUDE_DIR SQLITE_LIBRARIES )
|
||||||
|
|
90
akonadi/cmake/modules/InstallSettings.cmake
Normal file
90
akonadi/cmake/modules/InstallSettings.cmake
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
# Copyright (c) 2008 Kevin Krammer <kevin.krammer@gmx.at>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
set (LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)")
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
# use relative install prefix to avoid hardcoded install paths in cmake_install.cmake files
|
||||||
|
|
||||||
|
set (EXEC_INSTALL_PREFIX "") # Base directory for executables and libraries
|
||||||
|
|
||||||
|
## ${CMAKE_INSTALL_PREFIX}/*
|
||||||
|
set (BIN_INSTALL_DIR "bin") # The install dir for executables (default ${EXEC_INSTALL_PREFIX}/bin)
|
||||||
|
set (INCLUDE_INSTALL_DIR "include") # The subdirectory to the header prefix
|
||||||
|
set (LIB_INSTALL_DIR "lib${LIB_SUFFIX}") # The subdirectory relative to the install prefix where libraries will be installed (default is ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX})
|
||||||
|
set (SHARE_INSTALL_PREFIX "share") # Base directory for files which go to share/
|
||||||
|
|
||||||
|
## ${CMAKE_INSTALL_PREFIX}/share/*
|
||||||
|
set (CONFIG_INSTALL_DIR "share/config") # The config file install dir
|
||||||
|
set (DBUS_INTERFACES_INSTALL_DIR "share/dbus-1/interfaces") # The DBus interfaces install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/interfaces)")
|
||||||
|
set (DBUS_SERVICES_INSTALL_DIR "share/dbus-1/services") # The DBus services install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/services)")
|
||||||
|
set (XDG_MIME_INSTALL_DIR "share/mime/packages") # The install dir for the xdg mimetypes
|
||||||
|
|
||||||
|
else (WIN32)
|
||||||
|
# this macro implements some very special logic how to deal with the cache
|
||||||
|
# by default the various install locations inherit their value from theit "parent" variable
|
||||||
|
# so if you set CMAKE_INSTALL_PREFIX, then EXEC_INSTALL_PREFIX, PLUGIN_INSTALL_DIR will
|
||||||
|
# calculate their value by appending subdirs to CMAKE_INSTALL_PREFIX
|
||||||
|
# this would work completely without using the cache.
|
||||||
|
# but if somebody wants e.g. a different EXEC_INSTALL_PREFIX this value has to go into
|
||||||
|
# the cache, otherwise it will be forgotten on the next cmake run.
|
||||||
|
# Once a variable is in the cache, it doesn't depend on its "parent" variables
|
||||||
|
# anymore and you can only change it by editing it directly.
|
||||||
|
# this macro helps in this regard, because as long as you don't set one of the
|
||||||
|
# variables explicitely to some location, it will always calculate its value from its
|
||||||
|
# parents. So modifying CMAKE_INSTALL_PREFIX later on will have the desired effect.
|
||||||
|
# But once you decide to set e.g. EXEC_INSTALL_PREFIX to some special location
|
||||||
|
# this will go into the cache and it will no longer depend on CMAKE_INSTALL_PREFIX.
|
||||||
|
macro(_SET_FANCY _var _value _comment)
|
||||||
|
SET (predefinedvalue "${_value}")
|
||||||
|
|
||||||
|
if (NOT DEFINED ${_var})
|
||||||
|
SET (${_var} ${predefinedvalue})
|
||||||
|
else (NOT DEFINED ${_var})
|
||||||
|
SET (${_var} "${${_var}}" CACHE PATH "${_comment}")
|
||||||
|
endif (NOT DEFINED ${_var})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
_set_fancy(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" "Base directory for executables and libraries")
|
||||||
|
|
||||||
|
## ${CMAKE_INSTALL_PREFIX}/*
|
||||||
|
_set_fancy(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" "The install dir for executables (default ${EXEC_INSTALL_PREFIX}/bin)")
|
||||||
|
_set_fancy(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" "The subdirectory to the header prefix")
|
||||||
|
_set_fancy(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}" "The subdirectory relative to the install prefix where libraries will be installed (default is ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX})")
|
||||||
|
_set_fancy(SHARE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share" "Base directory for files which go to share/")
|
||||||
|
|
||||||
|
|
||||||
|
## ${CMAKE_INSTALL_PREFIX}/share/*
|
||||||
|
_set_fancy(CONFIG_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/config" "The config file install dir")
|
||||||
|
_set_fancy(DBUS_INTERFACES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/dbus-1/interfaces" "The DBus interfaces install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/interfaces)")
|
||||||
|
_set_fancy(DBUS_SERVICES_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/dbus-1/services" "The DBus services install dir (default ${SHARE_INSTALL_PREFIX}/dbus-1/services)")
|
||||||
|
_set_fancy(XDG_MIME_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/mime/packages" "The install dir for the xdg mimetypes")
|
||||||
|
|
||||||
|
endif (WIN32)
|
||||||
|
|
||||||
|
# The INSTALL_TARGETS_DEFAULT_ARGS variable should be used when libraries are installed.
|
||||||
|
# The arguments are also ok for regular executables, i.e. executables which don't go
|
||||||
|
# into sbin/ or libexec/, but for installing executables the basic syntax
|
||||||
|
# INSTALL(TARGETS kate DESTINATION "${BIN_INSTALL_DIR}")
|
||||||
|
# is enough, so using this variable there doesn't help a lot.
|
||||||
|
# The variable must not be used for installing plugins.
|
||||||
|
# Usage is like this:
|
||||||
|
# install(TARGETS kdecore kdeui ${INSTALL_TARGETS_DEFAULT_ARGS})
|
||||||
|
#
|
||||||
|
# This will install libraries correctly under UNIX, OSX and Windows (i.e. dll's go
|
||||||
|
# into bin/.
|
||||||
|
# Later on it will be possible to extend this for installing OSX frameworks
|
||||||
|
# The COMPONENT Devel argument has the effect that static libraries belong to the
|
||||||
|
# "Devel" install component. If we use this also for all install() commands
|
||||||
|
# for header files, it will be possible to install
|
||||||
|
# -everything: make install OR cmake -P cmake_install.cmake
|
||||||
|
# -only the development files: cmake -DCOMPONENT=Devel -P cmake_install.cmake
|
||||||
|
# -everything except the development files: cmake -DCOMPONENT=Unspecified -P cmake_install.cmake
|
||||||
|
# This can then also be used for packaging with cpack.
|
||||||
|
|
||||||
|
SET (INSTALL_TARGETS_DEFAULT_ARGS RUNTIME DESTINATION "${BIN_INSTALL_DIR}"
|
||||||
|
LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
|
||||||
|
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}" COMPONENT Devel)
|
117
akonadi/cmake/modules/MacroEnsureVersion.cmake
Normal file
117
akonadi/cmake/modules/MacroEnsureVersion.cmake
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
# This file defines the following macros for developers to use in ensuring
|
||||||
|
# that installed software is of the right version:
|
||||||
|
#
|
||||||
|
# MACRO_ENSURE_VERSION - test that a version number is greater than
|
||||||
|
# or equal to some minimum
|
||||||
|
# MACRO_ENSURE_VERSION_RANGE - test that a version number is greater than
|
||||||
|
# or equal to some minimum and less than some
|
||||||
|
# maximum
|
||||||
|
# MACRO_ENSURE_VERSION2 - deprecated, do not use in new code
|
||||||
|
#
|
||||||
|
|
||||||
|
# MACRO_ENSURE_VERSION
|
||||||
|
# This macro compares version numbers of the form "x.y.z" or "x.y"
|
||||||
|
# MACRO_ENSURE_VERSION( FOO_MIN_VERSION FOO_VERSION_FOUND FOO_VERSION_OK)
|
||||||
|
# will set FOO_VERSION_OK to true if FOO_VERSION_FOUND >= FOO_MIN_VERSION
|
||||||
|
# Leading and trailing text is ok, e.g.
|
||||||
|
# MACRO_ENSURE_VERSION( "2.5.31" "flex 2.5.4a" VERSION_OK)
|
||||||
|
# which means 2.5.31 is required and "flex 2.5.4a" is what was found on the system
|
||||||
|
|
||||||
|
# Copyright (c) 2006, David Faure, <faure@kde.org>
|
||||||
|
# Copyright (c) 2007, Will Stephenson <wstephenson@kde.org>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
# MACRO_ENSURE_VERSION_RANGE
|
||||||
|
# This macro ensures that a version number of the form
|
||||||
|
# "x.y.z" or "x.y" falls within a range defined by
|
||||||
|
# min_version <= found_version < max_version.
|
||||||
|
# If this expression holds, FOO_VERSION_OK will be set TRUE
|
||||||
|
#
|
||||||
|
# Example: MACRO_ENSURE_VERSION_RANGE3( "0.1.0" ${FOOCODE_VERSION} "0.7.0" FOO_VERSION_OK )
|
||||||
|
#
|
||||||
|
# This macro will break silently if any of x,y,z are greater than 100.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2007, Will Stephenson <wstephenson@kde.org>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
# NORMALIZE_VERSION
|
||||||
|
# Helper macro to convert version numbers of the form "x.y.z"
|
||||||
|
# to an integer equal to 10^4 * x + 10^2 * y + z
|
||||||
|
#
|
||||||
|
# This macro will break silently if any of x,y,z are greater than 100.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006, David Faure, <faure@kde.org>
|
||||||
|
# Copyright (c) 2007, Will Stephenson <wstephenson@kde.org>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
# CHECK_RANGE_INCLUSIVE_LOWER
|
||||||
|
# Helper macro to check whether x <= y < z
|
||||||
|
#
|
||||||
|
# Copyright (c) 2007, Will Stephenson <wstephenson@kde.org>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
|
||||||
|
|
||||||
|
MACRO(NORMALIZE_VERSION _requested_version _normalized_version)
|
||||||
|
STRING(REGEX MATCH "[^0-9]*[0-9]+\\.[0-9]+\\.[0-9]+.*" _threePartMatch "${_requested_version}")
|
||||||
|
if (_threePartMatch)
|
||||||
|
# parse the parts of the version string
|
||||||
|
STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" _major_vers "${_requested_version}")
|
||||||
|
STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" _minor_vers "${_requested_version}")
|
||||||
|
STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" _patch_vers "${_requested_version}")
|
||||||
|
else (_threePartMatch)
|
||||||
|
STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+" "\\1" _major_vers "${_requested_version}")
|
||||||
|
STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)" "\\1" _minor_vers "${_requested_version}")
|
||||||
|
set(_patch_vers "0")
|
||||||
|
endif (_threePartMatch)
|
||||||
|
|
||||||
|
# compute an overall version number which can be compared at once
|
||||||
|
MATH(EXPR ${_normalized_version} "${_major_vers}*10000 + ${_minor_vers}*100 + ${_patch_vers}")
|
||||||
|
ENDMACRO(NORMALIZE_VERSION)
|
||||||
|
|
||||||
|
MACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER _lower_limit _value _upper_limit _ok)
|
||||||
|
if (${_value} LESS ${_lower_limit})
|
||||||
|
set( ${_ok} FALSE )
|
||||||
|
elseif (${_value} EQUAL ${_lower_limit})
|
||||||
|
set( ${_ok} TRUE )
|
||||||
|
elseif (${_value} EQUAL ${_upper_limit})
|
||||||
|
set( ${_ok} FALSE )
|
||||||
|
elseif (${_value} GREATER ${_upper_limit})
|
||||||
|
set( ${_ok} FALSE )
|
||||||
|
else (${_value} LESS ${_lower_limit})
|
||||||
|
set( ${_ok} TRUE )
|
||||||
|
endif (${_value} LESS ${_lower_limit})
|
||||||
|
ENDMACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER)
|
||||||
|
|
||||||
|
MACRO(MACRO_ENSURE_VERSION requested_version found_version var_too_old)
|
||||||
|
NORMALIZE_VERSION( ${requested_version} req_vers_num )
|
||||||
|
NORMALIZE_VERSION( ${found_version} found_vers_num )
|
||||||
|
|
||||||
|
if (found_vers_num LESS req_vers_num)
|
||||||
|
set( ${var_too_old} FALSE )
|
||||||
|
else (found_vers_num LESS req_vers_num)
|
||||||
|
set( ${var_too_old} TRUE )
|
||||||
|
endif (found_vers_num LESS req_vers_num)
|
||||||
|
|
||||||
|
ENDMACRO(MACRO_ENSURE_VERSION)
|
||||||
|
|
||||||
|
MACRO(MACRO_ENSURE_VERSION2 requested_version2 found_version2 var_too_old2)
|
||||||
|
MACRO_ENSURE_VERSION( ${requested_version2} ${found_version2} ${var_too_old2})
|
||||||
|
ENDMACRO(MACRO_ENSURE_VERSION2)
|
||||||
|
|
||||||
|
MACRO(MACRO_ENSURE_VERSION_RANGE min_version found_version max_version var_ok)
|
||||||
|
NORMALIZE_VERSION( ${min_version} req_vers_num )
|
||||||
|
NORMALIZE_VERSION( ${found_version} found_vers_num )
|
||||||
|
NORMALIZE_VERSION( ${max_version} max_vers_num )
|
||||||
|
|
||||||
|
MACRO_CHECK_RANGE_INCLUSIVE_LOWER( ${req_vers_num} ${found_vers_num} ${max_vers_num} ${var_ok})
|
||||||
|
ENDMACRO(MACRO_ENSURE_VERSION_RANGE)
|
||||||
|
|
||||||
|
|
56
akonadi/cmake/modules/cmake-copyright.txt
Normal file
56
akonadi/cmake/modules/cmake-copyright.txt
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
CMake - Cross Platform Makefile Generator
|
||||||
|
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||||
|
nor the names of their contributors may be used to endorse or promote
|
||||||
|
products derived from this software without specific prior written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
The above copyright and license notice applies to distributions of
|
||||||
|
CMake in source and binary form. Some source files contain additional
|
||||||
|
notices of original copyright by their contributors; see each source
|
||||||
|
for details. Third-party software packages supplied with CMake under
|
||||||
|
compatible licenses provide their own copyright notices documented in
|
||||||
|
corresponding subdirectories.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CMake was initially developed by Kitware with the following sponsorship:
|
||||||
|
|
||||||
|
* National Library of Medicine at the National Institutes of Health
|
||||||
|
as part of the Insight Segmentation and Registration Toolkit (ITK).
|
||||||
|
|
||||||
|
* US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
|
||||||
|
Visualization Initiative.
|
||||||
|
|
||||||
|
* National Alliance for Medical Image Computing (NAMIC) is funded by the
|
||||||
|
National Institutes of Health through the NIH Roadmap for Medical Research,
|
||||||
|
Grant U54 EB005149.
|
||||||
|
|
||||||
|
* Kitware, Inc.
|
14
akonadi/config-akonadi.h.cmake
Normal file
14
akonadi/config-akonadi.h.cmake
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#cmakedefine01 Backtrace_FOUND
|
||||||
|
#if Backtrace_FOUND
|
||||||
|
# include <@Backtrace_HEADER@>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#cmakedefine HAVE_UNISTD_H 1
|
||||||
|
#cmakedefine HAVE_SOPRANO 1
|
||||||
|
|
||||||
|
#define AKONADI_VERSION_MAJOR @AKONADI_VERSION_MAJOR@
|
||||||
|
#define AKONADI_VERSION_MINOR @AKONADI_VERSION_MINOR@
|
||||||
|
#define AKONADI_VERSION_PATCH @AKONADI_VERSION_PATCH@
|
||||||
|
#define AKONADI_VERSION_STRING "@AKONADI_VERSION_STRING@"
|
||||||
|
|
||||||
|
#define AKONADI_DATABASE_BACKEND "@AKONADI_DATABASE_BACKEND@"
|
20
akonadi/interfaces/CMakeLists.txt
Normal file
20
akonadi/interfaces/CMakeLists.txt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
SET(DBUS_INTERFACE_XMLS
|
||||||
|
org.freedesktop.Akonadi.AgentManager.xml
|
||||||
|
org.freedesktop.Akonadi.NotificationManager.xml
|
||||||
|
org.freedesktop.Akonadi.Preprocessor.xml
|
||||||
|
org.freedesktop.Akonadi.Tracer.xml
|
||||||
|
org.freedesktop.Akonadi.Agent.Control.xml
|
||||||
|
org.freedesktop.Akonadi.Agent.Search.xml
|
||||||
|
org.freedesktop.Akonadi.Agent.Status.xml
|
||||||
|
org.freedesktop.Akonadi.Resource.xml
|
||||||
|
org.freedesktop.Akonadi.ControlManager.xml
|
||||||
|
org.freedesktop.Akonadi.NotificationSource.xml
|
||||||
|
org.freedesktop.Akonadi.Server.xml
|
||||||
|
org.freedesktop.Akonadi.StorageDebugger.xml
|
||||||
|
org.freedesktop.Akonadi.TracerNotification.xml
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES ${DBUS_INTERFACE_XMLS}
|
||||||
|
DESTINATION ${DBUS_INTERFACES_INSTALL_DIR})
|
||||||
|
|
||||||
|
|
19
akonadi/interfaces/org.freedesktop.Akonadi.Agent.Control.xml
Normal file
19
akonadi/interfaces/org.freedesktop.Akonadi.Agent.Control.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.Agent.Control">
|
||||||
|
<method name="quit">
|
||||||
|
</method>
|
||||||
|
<method name="cleanup">
|
||||||
|
</method>
|
||||||
|
<method name="configure">
|
||||||
|
<arg name="windowId" type="x" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<signal name="configurationDialogAccepted"/>
|
||||||
|
<signal name="configurationDialogRejected"/>
|
||||||
|
<method name="reconfigure">
|
||||||
|
</method>
|
||||||
|
<method name="abort">
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
21
akonadi/interfaces/org.freedesktop.Akonadi.Agent.Search.xml
Normal file
21
akonadi/interfaces/org.freedesktop.Akonadi.Agent.Search.xml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.Agent.Search">
|
||||||
|
<method name="addSearch">
|
||||||
|
<arg name="query" type="s" direction="in"/>
|
||||||
|
<arg name="queryLanguage" type="s" direction="in"/>
|
||||||
|
<arg name="destination" type="x" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="removeSearch">
|
||||||
|
<arg name="destination" type="x" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="search">
|
||||||
|
<arg name="searchId" type="ay" direction="in"/>
|
||||||
|
<arg name="query" type="s" direction="in"/>
|
||||||
|
<arg name="collection" type="x" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
41
akonadi/interfaces/org.freedesktop.Akonadi.Agent.Status.xml
Normal file
41
akonadi/interfaces/org.freedesktop.Akonadi.Agent.Status.xml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.Agent.Status">
|
||||||
|
<signal name="status">
|
||||||
|
<arg name="status" type="i" direction="out"/>
|
||||||
|
<arg name="message" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="percent">
|
||||||
|
<arg name="percent" type="i" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="warning">
|
||||||
|
<arg name="message" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="error">
|
||||||
|
<arg name="message" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="onlineChanged">
|
||||||
|
<arg name="state" type="b" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="advancedStatus">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
|
||||||
|
<arg name="status" type="a{sv}" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<method name="status">
|
||||||
|
<arg type="i" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<method name="statusMessage">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<method name="progress">
|
||||||
|
<arg type="i" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<method name="isOnline">
|
||||||
|
<arg type="b" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<method name="setOnline">
|
||||||
|
<arg name="state" type="b" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
160
akonadi/interfaces/org.freedesktop.Akonadi.AgentManager.xml
Normal file
160
akonadi/interfaces/org.freedesktop.Akonadi.AgentManager.xml
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.AgentManager">
|
||||||
|
<signal name="agentTypeAdded">
|
||||||
|
<arg name="agentType" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentTypeRemoved">
|
||||||
|
<arg name="agentType" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentInstanceAdded">
|
||||||
|
<arg name="agentIdentifier" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentInstanceRemoved">
|
||||||
|
<arg name="agentIdentifier" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentInstanceStatusChanged">
|
||||||
|
<arg name="agentIdentifier" type="s" direction="out"/>
|
||||||
|
<arg name="status" type="i" direction="out"/>
|
||||||
|
<arg name="message" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentInstanceAdvancedStatusChanged">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
|
||||||
|
<arg name="agentIdentifier" type="s" direction="out"/>
|
||||||
|
<arg name="status" type="a{sv}" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentInstanceProgressChanged">
|
||||||
|
<arg name="agentIdentifier" type="s" direction="out"/>
|
||||||
|
<arg name="progress" type="u" direction="out"/>
|
||||||
|
<arg name="message" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentInstanceNameChanged">
|
||||||
|
<arg name="agentIdentifier" type="s" direction="out"/>
|
||||||
|
<arg name="name" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentInstanceWarning">
|
||||||
|
<arg name="agentIdentifier" type="s" direction="out"/>
|
||||||
|
<arg name="message" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentInstanceError">
|
||||||
|
<arg name="agentIdentifier" type="s" direction="out"/>
|
||||||
|
<arg name="message" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="agentInstanceOnlineChanged">
|
||||||
|
<arg name="agentIdentifier" type="s" direction="out"/>
|
||||||
|
<arg name="state" type="b" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
|
||||||
|
<method name="agentTypes">
|
||||||
|
<arg type="as" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentName">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentName">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="language" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentComment">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentComment">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="language" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentIcon">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentMimeTypes">
|
||||||
|
<arg type="as" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentCapabilities">
|
||||||
|
<arg type="as" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentCustomProperties">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
|
||||||
|
<arg type="a{sv}" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="createAgentInstance">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="removeAgentInstance">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceType">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstances">
|
||||||
|
<arg type="as" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceStatus">
|
||||||
|
<arg type="i" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceStatusMessage">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceProgress">
|
||||||
|
<arg type="u" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceProgressMessage">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="setAgentInstanceName">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="name" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceName">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceName">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="language" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceConfigure">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="windowId" type="x" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceSynchronize">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceSynchronizeCollectionTree">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceSynchronizeCollection">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="collection" type="x" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceSynchronizeCollection">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="collection" type="x" direction="in"/>
|
||||||
|
<arg name="recursive" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="agentInstanceOnline">
|
||||||
|
<arg type="b" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="setAgentInstanceOnline">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="state" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="restartAgentInstance">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.AgentManagerInternal">
|
||||||
|
<method name="addSearch">
|
||||||
|
<arg name="query" type="s" direction="in"/>
|
||||||
|
<arg name="queryLanguage" type="s" direction="in"/>
|
||||||
|
<arg name="destination" type="x" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="removeSearch">
|
||||||
|
<arg name="destination" type="x" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
22
akonadi/interfaces/org.freedesktop.Akonadi.AgentServer.xml
Normal file
22
akonadi/interfaces/org.freedesktop.Akonadi.AgentServer.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.AgentServer">
|
||||||
|
<method name="agentInstanceConfigure">
|
||||||
|
<arg name="identifier" type="s" direction="in" />
|
||||||
|
<arg name="windowId" type="x" direction="in" />
|
||||||
|
</method>
|
||||||
|
<method name="started">
|
||||||
|
<arg type="b" direction="out"/>
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="startAgent">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="typeIdentifier" type="s" direction="in"/>
|
||||||
|
<arg name="fileName" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="stopAgent">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="quit"/>
|
||||||
|
</interface>
|
||||||
|
</node>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.ControlManager">
|
||||||
|
<method name="shutdown"/>
|
||||||
|
</interface>
|
||||||
|
</node>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.NotificationManager">
|
||||||
|
<signal name="notify">
|
||||||
|
<arg name="message" type="a(ayiixsayxxsas)" direction="out"/>
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="const Akonadi::NotificationMessage::List &"/>
|
||||||
|
<!-- In0 annotation for compatibility with qdbusxml2cpp from Qt4.3.0 -->
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const Akonadi::NotificationMessage::List &"/>
|
||||||
|
</signal>
|
||||||
|
<method name="subscribe">
|
||||||
|
<arg type="s" name="identifier" direction="in"/>
|
||||||
|
<arg type="o" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<signal name="subscribed">
|
||||||
|
<arg type="s" name="identifier" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
|
||||||
|
<method name="subscribeV2">
|
||||||
|
<arg type="s" name="identifier" direction="in"/>
|
||||||
|
<arg type="b" name="serverSideMonitor" direction="in"/>
|
||||||
|
<arg type="o" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<method name="unsubscribe">
|
||||||
|
<arg type="s" name="identifier" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<signal name="unsubscribed">
|
||||||
|
<arg type="s" name="identifier" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
|
||||||
|
<method name="subscribers">
|
||||||
|
<arg type="as" direction="out" />
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
|
@ -0,0 +1,112 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.NotificationSource">
|
||||||
|
<signal name="notify">
|
||||||
|
<arg name="message" type="a(ayiixsayxxsas)" direction="out"/>
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="const Akonadi::NotificationMessage::List &"/>
|
||||||
|
<!-- In0 annotation for compatibility with qdbusxml2cpp from Qt4.3.0 -->
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const Akonadi::NotificationMessage::List &"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="notifyV2">
|
||||||
|
<arg name="message" type="a(ayiia(xsss)ayayxxasaayaay)" direction="out"/>
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="const Akonadi::NotificationMessageV2::List &"/>
|
||||||
|
<!-- In0 annotation for compatibility with qdbusxml2cpp from Qt4.3.0 -->
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const Akonadi::NotificationMessageV2::List &"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="notifyV3">
|
||||||
|
<arg name="message" type="a(ayiia(xsss)ayayxxasaayaayaiai)" direction="out"/>
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="const Akonadi::NotificationMessageV3::List &"/>
|
||||||
|
<!-- In0 annotation for compatibility with qdbusxml2cpp from Qt4.3.0 -->
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const Akonadi::NotificationMessageV3::List &"/>
|
||||||
|
</signal>
|
||||||
|
<method name="unsubscribe">
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="setMonitoredCollection">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="Akonadi::Entity::Id"/>
|
||||||
|
<arg name="collection" type="x" direction="in"/>
|
||||||
|
<arg name="monitored" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="monitoredCollections">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVector<qint64>"/>
|
||||||
|
<arg type="ax" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<signal name="monitoredCollectionsChanged" />
|
||||||
|
|
||||||
|
<method name="setMonitoredItem">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="Akonadi::Entity::Id"/>
|
||||||
|
<arg name="item" type="x" direction="in"/>
|
||||||
|
<arg name="monitored" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="monitoredItems">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVector<qint64>"/>
|
||||||
|
<arg type="ax" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<signal name="monitoredItemsChanged" />
|
||||||
|
|
||||||
|
<method name="setMonitoredTag">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="Akonadi::Entity::Id"/>
|
||||||
|
<arg name="tag" type="x" direction="in"/>
|
||||||
|
<arg name="monitored" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="monitoredTags">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVector<qint64>"/>
|
||||||
|
<arg type="ax" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<signal name="monitoredTagsChanged"/>
|
||||||
|
|
||||||
|
<method name="setMonitoredType">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="Akonadi::NotificationMessageV2::Type"/>
|
||||||
|
<arg name="type" type="(i)" direction="in"/>
|
||||||
|
<arg name="monitored" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="monitoredTypes">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVector<Akonadi::NotificationMessageV2::Type>"/>
|
||||||
|
<arg type="a(i)" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<signal name="monitoredTypesChanged"/>
|
||||||
|
|
||||||
|
<method name="setMonitoredResource">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const QByteArray &"/>
|
||||||
|
<arg name="resource" type="ay" direction="in"/>
|
||||||
|
<arg name="monitored" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="monitoredResources">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVector<QByteArray>"/>
|
||||||
|
<arg type="aay" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<signal name="monitoredResourcesChanged" />
|
||||||
|
|
||||||
|
<method name="setMonitoredMimeType">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const QString &"/>
|
||||||
|
<arg name="mimetype" type="s" direction="in"/>
|
||||||
|
<arg name="monitored" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="monitoredMimeTypes">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="const QStringList &"/>
|
||||||
|
<arg type="as" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<signal name="monitoredMimeTypesChanged" />
|
||||||
|
|
||||||
|
<method name="setAllMonitored">
|
||||||
|
<arg name="allMonitored" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="isAllMonitored">
|
||||||
|
<arg type="b" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<signal name="isAllMonitoredChanged" />
|
||||||
|
|
||||||
|
<method name="setIgnoredSession">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const QByteArray &"/>
|
||||||
|
<arg name="session" type="ay" direction="in"/>
|
||||||
|
<arg name="ignored" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="ignoredSessions">
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVector<QByteArray>"/>
|
||||||
|
<arg type="aay" direction="out"/>
|
||||||
|
</method>
|
||||||
|
<signal name="ignoredSessionsChanged"/>
|
||||||
|
|
||||||
|
</interface>
|
||||||
|
</node>
|
||||||
|
|
14
akonadi/interfaces/org.freedesktop.Akonadi.Preprocessor.xml
Normal file
14
akonadi/interfaces/org.freedesktop.Akonadi.Preprocessor.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.Preprocessor">
|
||||||
|
<signal name="itemProcessed">
|
||||||
|
<arg name="id" type="x" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<method name="beginProcessItem">
|
||||||
|
<arg name="id" type="x" direction="in"/>
|
||||||
|
<arg name="collectionId" type="x" direction="in"/>
|
||||||
|
<arg name="mimeType" type="s" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.PreprocessorManager">
|
||||||
|
<method name="registerInstance">
|
||||||
|
<arg name="id" type="s" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="unregisterInstance">
|
||||||
|
<arg name="id" type="s" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
52
akonadi/interfaces/org.freedesktop.Akonadi.Resource.xml
Normal file
52
akonadi/interfaces/org.freedesktop.Akonadi.Resource.xml
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.Resource">
|
||||||
|
<signal name="nameChanged">
|
||||||
|
<arg name="name" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="synchronized"/>
|
||||||
|
<signal name="attributesSynchronized">
|
||||||
|
<arg type="x" name="collectionId"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="collectionTreeSynchronized"/>
|
||||||
|
<method name="requestItemDelivery">
|
||||||
|
<arg type="b" direction="out"/>
|
||||||
|
<arg name="uid" type="x" direction="in"/>
|
||||||
|
<arg name="remoteId" type="s" direction="in"/>
|
||||||
|
<arg name="mimeType" type="s" direction="in"/>
|
||||||
|
<arg name="parts" type="as" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="requestItemDeliveryV2">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
<arg name="uid" type="x" direction="in"/>
|
||||||
|
<arg name="remoteId" type="s" direction="in"/>
|
||||||
|
<arg name="mimeType" type="s" direction="in"/>
|
||||||
|
<arg name="parts" type="as" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="synchronize">
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="synchronizeCollectionTree">
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="synchronizeCollection">
|
||||||
|
<arg name="collectionId" type="x" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="synchronizeCollection">
|
||||||
|
<arg name="collectionId" type="x" direction="in"/>
|
||||||
|
<arg name="recursive" type="b" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="synchronizeCollectionAttributes">
|
||||||
|
<arg name="collectionId" type="x" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="setName">
|
||||||
|
<arg name="name" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="name">
|
||||||
|
<arg type="s" direction="out"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.ResourceManager">
|
||||||
|
<method name="addResourceInstance">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
<arg name="capabilities" type="as" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="removeResourceInstance">
|
||||||
|
<arg name="identifier" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="resourceInstances">
|
||||||
|
<arg type="as" direction="out"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
13
akonadi/interfaces/org.freedesktop.Akonadi.SearchManager.xml
Normal file
13
akonadi/interfaces/org.freedesktop.Akonadi.SearchManager.xml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.SearchManager">
|
||||||
|
<method name="registerInstance">
|
||||||
|
<arg name="id" type="s" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
<method name="unregisterInstance">
|
||||||
|
<arg name="id" type="s" direction="in"/>
|
||||||
|
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
6
akonadi/interfaces/org.freedesktop.Akonadi.Server.xml
Normal file
6
akonadi/interfaces/org.freedesktop.Akonadi.Server.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.Server">
|
||||||
|
<method name="quit"/>
|
||||||
|
</interface>
|
||||||
|
</node>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.StorageDebugger">
|
||||||
|
<method name="enableSQLDebugging">
|
||||||
|
<arg type="b" name="enable" direction="in" />
|
||||||
|
</method>
|
||||||
|
<method name="isSQLDebuggingEnabled">
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<signal name="queryExecuted">
|
||||||
|
<arg type="d" name="sequence" direction="out" />
|
||||||
|
<arg type="u" name="duration" direction="out" />
|
||||||
|
<arg type="s" name="query" direction="out" />
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In3" value="const QMap<QString,QVariant> &"/>
|
||||||
|
<arg type="{sv}" name="values" direction="out" />
|
||||||
|
<arg type="i" name="resultsCount" direction="out"/>
|
||||||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.In5" value="const QList<QList<QVariant> > &"/>
|
||||||
|
<arg type="aav" name="result" direction="out" />
|
||||||
|
<arg type="s" name="error" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
|
||||||
|
</interface>
|
||||||
|
</node>
|
17
akonadi/interfaces/org.freedesktop.Akonadi.Tracer.xml
Normal file
17
akonadi/interfaces/org.freedesktop.Akonadi.Tracer.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.Tracer">
|
||||||
|
<method name="signal">
|
||||||
|
<arg name="signalName" type="s" direction="in"/>
|
||||||
|
<arg name="msg" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="warning">
|
||||||
|
<arg name="componentName" type="s" direction="in"/>
|
||||||
|
<arg name="msg" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="error">
|
||||||
|
<arg name="componentName" type="s" direction="in"/>
|
||||||
|
<arg name="msg" type="s" direction="in"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.Akonadi.TracerNotification">
|
||||||
|
<signal name="connectionStarted">
|
||||||
|
<arg name="identifier" type="s" direction="out"/>
|
||||||
|
<arg name="msg" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="connectionEnded">
|
||||||
|
<arg name="identifier" type="s" direction="out"/>
|
||||||
|
<arg name="msg" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="connectionDataInput">
|
||||||
|
<arg name="identifier" type="s" direction="out"/>
|
||||||
|
<arg name="msg" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="connectionDataOutput">
|
||||||
|
<arg name="identifier" type="s" direction="out"/>
|
||||||
|
<arg name="msg" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="signalEmitted">
|
||||||
|
<arg name="signalName" type="s" direction="out"/>
|
||||||
|
<arg name="msg" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="warningEmitted">
|
||||||
|
<arg name="componentName" type="s" direction="out"/>
|
||||||
|
<arg name="msg" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="errorEmitted">
|
||||||
|
<arg name="componentName" type="s" direction="out"/>
|
||||||
|
<arg name="msg" type="s" direction="out"/>
|
||||||
|
</signal>
|
||||||
|
</interface>
|
||||||
|
</node>
|
504
akonadi/lgpl-license
Normal file
504
akonadi/lgpl-license
Normal file
|
@ -0,0 +1,504 @@
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for
|
||||||
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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 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; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
40
akonadi/libs/CMakeLists.txt
Normal file
40
akonadi/libs/CMakeLists.txt
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_ENABLE_EXCEPTIONS}")
|
||||||
|
|
||||||
|
configure_file(akonadiprotocolinternals_export.h.in ${Akonadi_BINARY_DIR}/akonadiprotocolinternals_export.h)
|
||||||
|
|
||||||
|
# libakonadiprotocolinternals
|
||||||
|
set(akonadiprotocolinternals_srcs
|
||||||
|
imapparser.cpp
|
||||||
|
imapset.cpp
|
||||||
|
notificationmessage.cpp
|
||||||
|
notificationmessagev2.cpp
|
||||||
|
notificationmessagev3.cpp
|
||||||
|
xdgbasedirs.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(akonadiprotocolinternals ${LIBRARY_TYPE} ${akonadiprotocolinternals_srcs})
|
||||||
|
|
||||||
|
target_link_libraries(akonadiprotocolinternals ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY})
|
||||||
|
set_target_properties(akonadiprotocolinternals PROPERTIES
|
||||||
|
VERSION ${AKONADI_VERSION}
|
||||||
|
SOVERSION ${AKONADI_SOVERSION}
|
||||||
|
DEFINE_SYMBOL MAKE_AKONADIPROTOCOLINTERNALS_LIB
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS akonadiprotocolinternals EXPORT akonadiLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
${Akonadi_BINARY_DIR}/akonadiprotocolinternals_export.h
|
||||||
|
imapparser_p.h
|
||||||
|
imapset_p.h
|
||||||
|
notificationmessage_p.h
|
||||||
|
notificationmessagev2_p.h
|
||||||
|
notificationmessagev3_p.h
|
||||||
|
protocol_p.h
|
||||||
|
xdgbasedirs_p.h
|
||||||
|
capabilities_p.h
|
||||||
|
DESTINATION ${INCLUDE_INSTALL_DIR}/akonadi/private
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(tests)
|
||||||
|
|
40
akonadi/libs/akonadiprotocolinternals_export.h.in
Normal file
40
akonadi/libs/akonadiprotocolinternals_export.h.in
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/* This file is part of the KDE project
|
||||||
|
Copyright (C) 2007 David Faure <faure@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||||||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADIPROTOCOLINTERNALS_EXPORT_H
|
||||||
|
#define AKONADIPROTOCOLINTERNALS_EXPORT_H
|
||||||
|
|
||||||
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
|
#cmakedefine AKONADI_STATIC_LIBS
|
||||||
|
|
||||||
|
#ifndef AKONADIPROTOCOLINTERNALS_EXPORT
|
||||||
|
# if defined(AKONADI_STATIC_LIBS)
|
||||||
|
/* No export/import for static libraries */
|
||||||
|
# define AKONADIPROTOCOLINTERNALS_EXPORT
|
||||||
|
# elif defined(MAKE_AKONADIPROTOCOLINTERNALS_LIB)
|
||||||
|
/* We are building this library */
|
||||||
|
# define AKONADIPROTOCOLINTERNALS_EXPORT Q_DECL_EXPORT
|
||||||
|
# else
|
||||||
|
/* We are using this library */
|
||||||
|
# define AKONADIPROTOCOLINTERNALS_EXPORT Q_DECL_IMPORT
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
37
akonadi/libs/capabilities_p.h
Normal file
37
akonadi/libs/capabilities_p.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2009 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_CAPABILITIES_P_H
|
||||||
|
#define AKONADI_CAPABILITIES_P_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file capabilites_p.h Shared constants for agent capabilities.
|
||||||
|
|
||||||
|
@todo Fill this file with the missing capabilities.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define AKONADI_AGENT_CAPABILITY_AUTOSTART "Autostart"
|
||||||
|
#define AKONADI_AGENT_CAPABILITY_NOCONFIG "NoConfig"
|
||||||
|
#define AKONADI_AGENT_CAPABILITY_PREPROCESSOR "Preprocessor"
|
||||||
|
#define AKONADI_AGENT_CAPABILITY_RESOURCE "Resource"
|
||||||
|
#define AKONADI_AGENT_CAPABILITY_SEARCH "Search"
|
||||||
|
#define AKONADI_AGENT_CAPABILITY_UNIQUE "Unique"
|
||||||
|
#define AKONADI_AGENT_CAPABILITY_VIRTUAL "Virtual"
|
||||||
|
|
||||||
|
#endif
|
698
akonadi/libs/imapparser.cpp
Normal file
698
akonadi/libs/imapparser.cpp
Normal file
|
@ -0,0 +1,698 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "imapparser_p.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDateTime>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
class ImapParser::Private
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QByteArray tagBuffer;
|
||||||
|
QByteArray dataBuffer;
|
||||||
|
int parenthesesCount;
|
||||||
|
qint64 literalSize;
|
||||||
|
bool continuation;
|
||||||
|
|
||||||
|
// returns true if readBuffer contains a literal start and sets
|
||||||
|
// parser state accordingly
|
||||||
|
bool checkLiteralStart( const QByteArray &readBuffer, int pos = 0 )
|
||||||
|
{
|
||||||
|
if ( readBuffer.trimmed().endsWith( '}' ) ) {
|
||||||
|
const int begin = readBuffer.lastIndexOf( '{' );
|
||||||
|
const int end = readBuffer.lastIndexOf( '}' );
|
||||||
|
|
||||||
|
// new literal in previous literal data block
|
||||||
|
if ( begin < pos ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO error handling
|
||||||
|
literalSize = readBuffer.mid( begin + 1, end - begin - 1 ).toLongLong();
|
||||||
|
|
||||||
|
// empty literal
|
||||||
|
if ( literalSize == 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
continuation = true;
|
||||||
|
dataBuffer.reserve( dataBuffer.size() + literalSize + 1 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int parseParenthesizedListHelper( const QByteArray &data, T &result, int start )
|
||||||
|
{
|
||||||
|
result.clear();
|
||||||
|
if ( start >= data.length() ) {
|
||||||
|
return data.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
const int begin = data.indexOf( '(', start );
|
||||||
|
if ( begin < 0 ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
int sublistBegin = start;
|
||||||
|
bool insideQuote = false;
|
||||||
|
for ( int i = begin + 1; i < data.length(); ++i ) {
|
||||||
|
const char currentChar = data[i];
|
||||||
|
if ( currentChar == '(' && !insideQuote ) {
|
||||||
|
++count;
|
||||||
|
if ( count == 1 ) {
|
||||||
|
sublistBegin = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( currentChar == ')' && !insideQuote ) {
|
||||||
|
if ( count <= 0 ) {
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count == 1 ) {
|
||||||
|
result.append( data.mid( sublistBegin, i - sublistBegin + 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
--count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( currentChar == ' ' || currentChar == '\n' || currentChar == '\r' ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count == 0 ) {
|
||||||
|
QByteArray ba;
|
||||||
|
const int consumed = ImapParser::parseString( data, ba, i );
|
||||||
|
i = consumed - 1; // compensate for the for loop increment
|
||||||
|
result.append( ba );
|
||||||
|
} else if ( count > 0 ) {
|
||||||
|
if ( currentChar == '"' ) {
|
||||||
|
insideQuote = !insideQuote;
|
||||||
|
} else if ( currentChar == '\\' && insideQuote ) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::parseParenthesizedList( const QByteArray &data, QVarLengthArray<QByteArray,16> &result, int start )
|
||||||
|
{
|
||||||
|
return parseParenthesizedListHelper( data, result, start );
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::parseParenthesizedList( const QByteArray &data, QList<QByteArray> &result, int start )
|
||||||
|
{
|
||||||
|
return parseParenthesizedListHelper( data, result, start );
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::parseString( const QByteArray &data, QByteArray &result, int start )
|
||||||
|
{
|
||||||
|
int begin = stripLeadingSpaces( data, start );
|
||||||
|
result.clear();
|
||||||
|
if ( begin >= data.length() ) {
|
||||||
|
return data.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// literal string
|
||||||
|
// TODO: error handling
|
||||||
|
if ( data[begin] == '{' ) {
|
||||||
|
int end = data.indexOf( '}', begin );
|
||||||
|
Q_ASSERT( end > begin );
|
||||||
|
int size = data.mid( begin + 1, end - begin - 1 ).toInt();
|
||||||
|
|
||||||
|
// strip CRLF
|
||||||
|
begin = end + 1;
|
||||||
|
if ( begin < data.length() && data[begin] == '\r' ) {
|
||||||
|
++begin;
|
||||||
|
}
|
||||||
|
if ( begin < data.length() && data[begin] == '\n' ) {
|
||||||
|
++begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = begin + size;
|
||||||
|
result = data.mid( begin, end - begin );
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// quoted string
|
||||||
|
return parseQuotedString( data, result, begin );
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::parseQuotedString( const QByteArray &data, QByteArray &result, int start )
|
||||||
|
{
|
||||||
|
int begin = stripLeadingSpaces( data, start );
|
||||||
|
int end = begin;
|
||||||
|
result.clear();
|
||||||
|
if ( begin >= data.length() ) {
|
||||||
|
return data.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool foundSlash = false;
|
||||||
|
// quoted string
|
||||||
|
if ( data[begin] == '"' ) {
|
||||||
|
++begin;
|
||||||
|
for ( int i = begin; i < data.length(); ++i ) {
|
||||||
|
const char ch = data.at( i );
|
||||||
|
if ( foundSlash ) {
|
||||||
|
foundSlash = false;
|
||||||
|
if ( ch == 'r' ) {
|
||||||
|
result += '\r';
|
||||||
|
} else if ( ch == 'n' ) {
|
||||||
|
result += '\n';
|
||||||
|
} else if ( ch == '\\' ) {
|
||||||
|
result += '\\';
|
||||||
|
} else if ( ch == '\"' ) {
|
||||||
|
result += '\"';
|
||||||
|
} else {
|
||||||
|
//TODO: this is actually an error
|
||||||
|
result += ch;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( ch == '\\' ) {
|
||||||
|
foundSlash = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( ch == '"' ) {
|
||||||
|
end = i + 1; // skip the '"'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unquoted string
|
||||||
|
else {
|
||||||
|
bool reachedInputEnd = true;
|
||||||
|
for ( int i = begin; i < data.length(); ++i ) {
|
||||||
|
const char ch = data.at( i );
|
||||||
|
if ( ch == ' ' || ch == '(' || ch == ')' || ch == '\n' || ch == '\r' ) {
|
||||||
|
end = i;
|
||||||
|
reachedInputEnd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( ch == '\\' ) {
|
||||||
|
foundSlash = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( reachedInputEnd ) {
|
||||||
|
end = data.length();
|
||||||
|
}
|
||||||
|
result = data.mid( begin, end - begin );
|
||||||
|
|
||||||
|
// transform unquoted NIL
|
||||||
|
if ( result == "NIL" ) {
|
||||||
|
result.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip quotes
|
||||||
|
if ( foundSlash ) {
|
||||||
|
while ( result.contains( "\\\"" ) ) {
|
||||||
|
result.replace( "\\\"", "\"" );
|
||||||
|
}
|
||||||
|
while ( result.contains( "\\\\" ) ) {
|
||||||
|
result.replace( "\\\\", "\\" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::stripLeadingSpaces( const QByteArray &data, int start )
|
||||||
|
{
|
||||||
|
for ( int i = start; i < data.length(); ++i ) {
|
||||||
|
if ( data[i] != ' ' ) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::parenthesesBalance( const QByteArray &data, int start )
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
bool insideQuote = false;
|
||||||
|
for ( int i = start; i < data.length(); ++i ) {
|
||||||
|
const char ch = data[i];
|
||||||
|
if ( ch == '"' ) {
|
||||||
|
insideQuote = !insideQuote;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( ch == '\\' && insideQuote ) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( ch == '(' && !insideQuote ) {
|
||||||
|
++count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( ch == ')' && !insideQuote ) {
|
||||||
|
--count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ImapParser::join( const QList<QByteArray> &list, const QByteArray &separator )
|
||||||
|
{
|
||||||
|
// shortcuts for the easy cases
|
||||||
|
if ( list.isEmpty() ) {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
if ( list.size() == 1 ) {
|
||||||
|
return list.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
// avoid expensive realloc's by determining the size beforehand
|
||||||
|
QList<QByteArray>::const_iterator it = list.constBegin();
|
||||||
|
const QList<QByteArray>::const_iterator endIt = list.constEnd();
|
||||||
|
int resultSize = ( list.size() - 1 ) * separator.size();
|
||||||
|
for ( ; it != endIt; ++it ) {
|
||||||
|
resultSize += ( *it ).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray result;
|
||||||
|
result.reserve( resultSize );
|
||||||
|
it = list.constBegin();
|
||||||
|
result += ( *it );
|
||||||
|
++it;
|
||||||
|
for ( ; it != endIt; ++it ) {
|
||||||
|
result += separator;
|
||||||
|
result += ( *it );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ImapParser::join( const QSet<QByteArray> &set, const QByteArray &separator )
|
||||||
|
{
|
||||||
|
const QList<QByteArray> list = QList<QByteArray>::fromSet( set );
|
||||||
|
|
||||||
|
return ImapParser::join( list, separator );
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::parseString( const QByteArray &data, QString &result, int start )
|
||||||
|
{
|
||||||
|
QByteArray tmp;
|
||||||
|
const int end = parseString( data, tmp, start );
|
||||||
|
result = QString::fromUtf8( tmp );
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::parseNumber( const QByteArray &data, qint64 &result, bool *ok, int start )
|
||||||
|
{
|
||||||
|
if ( ok ) {
|
||||||
|
*ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = stripLeadingSpaces( data, start );
|
||||||
|
if ( pos >= data.length() ) {
|
||||||
|
return data.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
int begin = pos;
|
||||||
|
for ( ; pos < data.length(); ++pos ) {
|
||||||
|
if ( !isdigit( data.at( pos ) ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray tmp = data.mid( begin, pos - begin );
|
||||||
|
result = tmp.toLongLong( ok );
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ImapParser::quote( const QByteArray &data )
|
||||||
|
{
|
||||||
|
if ( data.isEmpty() ) {
|
||||||
|
return QByteArray( "\"\"" );
|
||||||
|
}
|
||||||
|
|
||||||
|
const int inputLength = data.length();
|
||||||
|
int stuffToQuote = 0;
|
||||||
|
for ( int i = 0; i < inputLength; ++i ) {
|
||||||
|
const char ch = data.at( i );
|
||||||
|
if ( ch == '"' || ch == '\\' || ch == '\n' || ch == '\r' ) {
|
||||||
|
++stuffToQuote;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray result;
|
||||||
|
result.reserve( inputLength + stuffToQuote + 2 );
|
||||||
|
result += '"';
|
||||||
|
|
||||||
|
// shortcut for the case that we don't need to quote anything at all
|
||||||
|
if ( stuffToQuote == 0 ) {
|
||||||
|
result += data;
|
||||||
|
} else {
|
||||||
|
for ( int i = 0; i < inputLength; ++i ) {
|
||||||
|
const char ch = data.at( i );
|
||||||
|
if ( ch == '\n' ) {
|
||||||
|
result += "\\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ch == '\r' ) {
|
||||||
|
result += "\\r";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ch == '"' || ch == '\\' ) {
|
||||||
|
result += '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
result += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result += '"';
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::parseSequenceSet( const QByteArray &data, ImapSet &result, int start )
|
||||||
|
{
|
||||||
|
int begin = stripLeadingSpaces( data, start );
|
||||||
|
qint64 value = -1, lower = -1, upper = -1;
|
||||||
|
for ( int i = begin; i < data.length(); ++i ) {
|
||||||
|
if ( data[i] == '*' ) {
|
||||||
|
value = 0;
|
||||||
|
} else if ( data[i] == ':' ) {
|
||||||
|
lower = value;
|
||||||
|
} else if ( isdigit( data[i] ) ) {
|
||||||
|
bool ok = false;
|
||||||
|
i = parseNumber( data, value, &ok, i );
|
||||||
|
Q_ASSERT( ok ); // TODO handle error
|
||||||
|
--i;
|
||||||
|
} else {
|
||||||
|
upper = value;
|
||||||
|
if ( lower < 0 ) {
|
||||||
|
lower = value;
|
||||||
|
}
|
||||||
|
result.add( ImapInterval( lower, upper ) );
|
||||||
|
lower = -1;
|
||||||
|
upper = -1;
|
||||||
|
value = -1;
|
||||||
|
if ( data[i] != ',' ) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// take care of left-overs at input end
|
||||||
|
upper = value;
|
||||||
|
if ( lower < 0 ) {
|
||||||
|
lower = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( lower >= 0 && upper >= 0 ) {
|
||||||
|
result.add( ImapInterval( lower, upper ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImapParser::parseDateTime( const QByteArray &data, QDateTime &dateTime, int start )
|
||||||
|
{
|
||||||
|
// Syntax:
|
||||||
|
// date-time = DQUOTE date-day-fixed "-" date-month "-" date-year
|
||||||
|
// SP time SP zone DQUOTE
|
||||||
|
// date-day-fixed = (SP DIGIT) / 2DIGIT
|
||||||
|
// ; Fixed-format version of date-day
|
||||||
|
// date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
|
||||||
|
// "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
|
||||||
|
// date-year = 4DIGIT
|
||||||
|
// time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
|
||||||
|
// ; Hours minutes seconds
|
||||||
|
// zone = ("+" / "-") 4DIGIT
|
||||||
|
// ; Signed four-digit value of hhmm representing
|
||||||
|
// ; hours and minutes east of Greenwich (that is,
|
||||||
|
// ; the amount that the given time differs from
|
||||||
|
// ; Universal Time). Subtracting the timezone
|
||||||
|
// ; from the given time will give the UT form.
|
||||||
|
// ; The Universal Time zone is "+0000".
|
||||||
|
// Example : "28-May-2006 01:03:35 +0200"
|
||||||
|
// Position: 0123456789012345678901234567
|
||||||
|
// 1 2
|
||||||
|
|
||||||
|
int pos = stripLeadingSpaces( data, start );
|
||||||
|
if ( data.length() <= pos ) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool quoted = false;
|
||||||
|
if ( data[pos] == '"' ) {
|
||||||
|
quoted = true;
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
if ( data.length() <= pos + 26 ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( data.length() < pos + 26 ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
|
const int day = ( data[pos] == ' ' ? data[pos + 1] - '0' // single digit day
|
||||||
|
: data.mid( pos, 2 ).toInt( &ok ) );
|
||||||
|
if ( !ok ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 3;
|
||||||
|
const QByteArray shortMonthNames( "janfebmaraprmayjunjulaugsepoctnovdec" );
|
||||||
|
int month = shortMonthNames.indexOf( data.mid( pos, 3 ).toLower() );
|
||||||
|
if ( month == -1 ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
month = month / 3 + 1;
|
||||||
|
pos += 4;
|
||||||
|
const int year = data.mid( pos, 4 ).toInt( &ok );
|
||||||
|
if ( !ok ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 5;
|
||||||
|
const int hours = data.mid( pos, 2 ).toInt( &ok );
|
||||||
|
if ( !ok ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 3;
|
||||||
|
const int minutes = data.mid( pos, 2 ).toInt( &ok );
|
||||||
|
if ( !ok ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 3;
|
||||||
|
const int seconds = data.mid( pos, 2 ).toInt( &ok );
|
||||||
|
if ( !ok ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 4;
|
||||||
|
const int tzhh = data.mid( pos, 2 ).toInt( &ok );
|
||||||
|
if ( !ok ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 2;
|
||||||
|
const int tzmm = data.mid( pos, 2 ).toInt( &ok );
|
||||||
|
if ( !ok ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tzsecs = tzhh * 60 * 60 + tzmm * 60;
|
||||||
|
if ( data[pos - 3] == '-' ) {
|
||||||
|
tzsecs = -tzsecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDate date( year, month, day );
|
||||||
|
const QTime time( hours, minutes, seconds );
|
||||||
|
dateTime = QDateTime( date, time, Qt::UTC );
|
||||||
|
if ( !dateTime.isValid() ) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
dateTime = dateTime.addSecs( -tzsecs );
|
||||||
|
|
||||||
|
pos += 2;
|
||||||
|
if ( data.length() <= pos || !quoted ) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( data[pos] == '"' ) {
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImapParser::splitVersionedKey( const QByteArray &data, QByteArray &key, int &version )
|
||||||
|
{
|
||||||
|
if ( data.contains( '[' ) && data.contains( ']' ) ) {
|
||||||
|
const int startPos = data.indexOf( '[' );
|
||||||
|
const int endPos = data.indexOf( ']' );
|
||||||
|
if ( startPos != -1 && endPos != -1 && endPos > startPos ) {
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
version = data.mid( startPos + 1, endPos - startPos - 1 ).toInt( &ok );
|
||||||
|
if ( !ok ) {
|
||||||
|
version = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = data.left( startPos );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
key = data;
|
||||||
|
version = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapParser::ImapParser()
|
||||||
|
: d ( new Private )
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapParser::~ImapParser()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImapParser::parseNextLine( const QByteArray &readBuffer )
|
||||||
|
{
|
||||||
|
d->continuation = false;
|
||||||
|
|
||||||
|
// first line, get the tag
|
||||||
|
if ( d->tagBuffer.isEmpty() ) {
|
||||||
|
const int startOfData = ImapParser::parseString( readBuffer, d->tagBuffer );
|
||||||
|
if ( startOfData < readBuffer.length() && startOfData >= 0 ) {
|
||||||
|
d->dataBuffer = readBuffer.mid( startOfData + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
d->dataBuffer += readBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// literal read in progress
|
||||||
|
if ( d->literalSize > 0 ) {
|
||||||
|
d->literalSize -= readBuffer.size();
|
||||||
|
|
||||||
|
// still not everything read
|
||||||
|
if ( d->literalSize > 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the remaining (non-literal) part for parentheses
|
||||||
|
if ( d->literalSize < 0 ) {
|
||||||
|
// the following looks strange but works since literalSize can be negative here
|
||||||
|
d->parenthesesCount += ImapParser::parenthesesBalance( readBuffer, readBuffer.length() + d->literalSize );
|
||||||
|
|
||||||
|
// check if another literal read was started
|
||||||
|
if ( d->checkLiteralStart( readBuffer, readBuffer.length() + d->literalSize ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// literal string finished but still open parentheses
|
||||||
|
if ( d->parenthesesCount > 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// open parentheses
|
||||||
|
d->parenthesesCount += ImapParser::parenthesesBalance( readBuffer );
|
||||||
|
|
||||||
|
// start new literal read
|
||||||
|
if ( d->checkLiteralStart( readBuffer ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// still open parentheses
|
||||||
|
if ( d->parenthesesCount > 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// just a normal response, fall through
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImapParser::parseBlock( const QByteArray &data )
|
||||||
|
{
|
||||||
|
Q_ASSERT( d->literalSize >= data.size() );
|
||||||
|
d->literalSize -= data.size();
|
||||||
|
d->dataBuffer += data;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ImapParser::tag() const
|
||||||
|
{
|
||||||
|
return d->tagBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ImapParser::data() const
|
||||||
|
{
|
||||||
|
return d->dataBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImapParser::reset()
|
||||||
|
{
|
||||||
|
d->dataBuffer.clear();
|
||||||
|
d->tagBuffer.clear();
|
||||||
|
d->parenthesesCount = 0;
|
||||||
|
d->literalSize = 0;
|
||||||
|
d->continuation = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImapParser::continuationStarted() const
|
||||||
|
{
|
||||||
|
return d->continuation;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 ImapParser::continuationSize() const
|
||||||
|
{
|
||||||
|
return d->literalSize;
|
||||||
|
}
|
211
akonadi/libs/imapparser_p.h
Normal file
211
akonadi/libs/imapparser_p.h
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_IMAPPARSER_P_H
|
||||||
|
#define AKONADI_IMAPPARSER_P_H
|
||||||
|
|
||||||
|
#include "akonadiprotocolinternals_export.h"
|
||||||
|
|
||||||
|
#include "imapset_p.h"
|
||||||
|
|
||||||
|
#include <QtCore/QByteArray>
|
||||||
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QVarLengthArray>
|
||||||
|
|
||||||
|
namespace Akonadi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parser for IMAP messages.
|
||||||
|
*/
|
||||||
|
class AKONADIPROTOCOLINTERNALS_EXPORT ImapParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Parses the next parenthesized list in @p data starting from @p start
|
||||||
|
and puts the result into @p result. The number of used characters is
|
||||||
|
returned.
|
||||||
|
This does not recurse into sub-lists.
|
||||||
|
@param data Source data.
|
||||||
|
@param result The parsed list.
|
||||||
|
@param start Start parsing at this index.
|
||||||
|
*/
|
||||||
|
static int parseParenthesizedList( const QByteArray &data, QList<QByteArray> &result, int start = 0 );
|
||||||
|
static int parseParenthesizedList( const QByteArray &data, QVarLengthArray<QByteArray,16> &result, int start = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parse the next string in @p data (quoted or literal) starting from @p start
|
||||||
|
and puts the result into @p result. The number of used characters is returned
|
||||||
|
(this is not equal to result.length()!).
|
||||||
|
@param data Source data.
|
||||||
|
@param result Parsed string, quotation, literal marker, etc. are removed,
|
||||||
|
'NIL' is transformed into an empty QByteArray.
|
||||||
|
@param start start parsing at this index.
|
||||||
|
*/
|
||||||
|
static int parseString( const QByteArray &data, QByteArray &result, int start = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parses the next quoted string from @p data starting at @p start and puts it into
|
||||||
|
@p result. The number of parsed characters is returned (this is not equal to result.length()!).
|
||||||
|
@param data Source data.
|
||||||
|
@param result Parsed string, quotation is removed and 'NIL' is transformed to an empty QByteArray.
|
||||||
|
@param start Start parsing at this index.
|
||||||
|
*/
|
||||||
|
static int parseQuotedString( const QByteArray &data, QByteArray &result, int start = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the number of leading espaces in @p data starting from @p start.
|
||||||
|
@param data The source data.
|
||||||
|
@param start Start parsing at this index.
|
||||||
|
*/
|
||||||
|
static int stripLeadingSpaces( const QByteArray &data, int start = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the parentheses balance for the given data, considering quotes.
|
||||||
|
@param data The source data.
|
||||||
|
@param start Start parsing at this index.
|
||||||
|
*/
|
||||||
|
static int parenthesesBalance( const QByteArray &data, int start = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Joins a QByteArray list with the given separator.
|
||||||
|
@param list The QByteArray list to join.
|
||||||
|
@param separator The separator.
|
||||||
|
*/
|
||||||
|
static QByteArray join( const QList<QByteArray> &list, const QByteArray &separator );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Joins a QByteArray set with the given separator.
|
||||||
|
@param set The QByteArray set to join.
|
||||||
|
@param separator The separator.
|
||||||
|
*/
|
||||||
|
static QByteArray join( const QSet<QByteArray> &set, const QByteArray &separator );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Same as parseString(), but with additional UTF-8 decoding of the result.
|
||||||
|
@param data Source data.
|
||||||
|
@param result Parsed string, quotation, literal marker, etc. are removed,
|
||||||
|
'NIL' is transformed into an empty QString. UTF-8 decoding is applied..
|
||||||
|
@param start Start parsing at this index.
|
||||||
|
*/
|
||||||
|
static int parseString( const QByteArray &data, QString &result, int start = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parses the next integer number from @p data starting at start and puts it into
|
||||||
|
@p result. The number of characters parsed is returned (this is not the parsed result!).
|
||||||
|
@param data Source data.
|
||||||
|
@param result Parsed integer number, invalid if ok is false.
|
||||||
|
@param ok Set to false if the parsing failed.
|
||||||
|
@param start Start parsing at this index.
|
||||||
|
*/
|
||||||
|
static int parseNumber( const QByteArray &data, qint64 &result, bool *ok = 0, int start = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Quotes the given QByteArray.
|
||||||
|
@param data Source data.
|
||||||
|
*/
|
||||||
|
static QByteArray quote( const QByteArray &data );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parse an IMAP sequence set.
|
||||||
|
@param data source data.
|
||||||
|
@param result The parse sequence set.
|
||||||
|
@param start start parsing at this index.
|
||||||
|
@return end position of parsing.
|
||||||
|
*/
|
||||||
|
static int parseSequenceSet( const QByteArray &data, ImapSet &result, int start = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parse an IMAP date/time value.
|
||||||
|
@param data source data.
|
||||||
|
@param dateTime The result date/time.
|
||||||
|
@param start Start parsing at this index.
|
||||||
|
@return end position of parsing.
|
||||||
|
*/
|
||||||
|
static int parseDateTime( const QByteArray &data, QDateTime &dateTime, int start = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Split a versioned key of the form 'key[version]' into its components.
|
||||||
|
@param data The versioned key.
|
||||||
|
@param key The unversioned key.
|
||||||
|
@param version The version of the key or 0 if no version was set.
|
||||||
|
*/
|
||||||
|
static void splitVersionedKey( const QByteArray &data, QByteArray &key, int &version );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constructs a new IMAP parser.
|
||||||
|
*/
|
||||||
|
ImapParser();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destroys an IMAP parser.
|
||||||
|
*/
|
||||||
|
~ImapParser();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parses the given line.
|
||||||
|
@returns True if an IMAP message was parsed completely, false if more data is needed.
|
||||||
|
@todo read from a QIODevice directly to avoid an extra line buffer
|
||||||
|
*/
|
||||||
|
bool parseNextLine( const QByteArray &readBuffer );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Parses the given block of data.
|
||||||
|
Note: This currently only handles continuation blocks.
|
||||||
|
@param data The data to parse.
|
||||||
|
*/
|
||||||
|
void parseBlock( const QByteArray &data );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the tag of the parsed message.
|
||||||
|
Only valid if parseNextLine() returned true.
|
||||||
|
*/
|
||||||
|
QByteArray tag() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the raw data of the parsed IMAP message.
|
||||||
|
Only valid if parseNextLine() returned true.
|
||||||
|
*/
|
||||||
|
QByteArray data() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Resets the internal state of the parser. Call before parsing
|
||||||
|
a new IMAP message.
|
||||||
|
*/
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns true if the last parsed line contained a literal continuation,
|
||||||
|
ie. readiness for receiving literal data needs to be indicated.
|
||||||
|
*/
|
||||||
|
bool continuationStarted() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the expected size of liteal data.
|
||||||
|
*/
|
||||||
|
qint64 continuationSize() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY( ImapParser )
|
||||||
|
class Private;
|
||||||
|
Private *const d;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
270
akonadi/libs/imapset.cpp
Normal file
270
akonadi/libs/imapset.cpp
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "imapset_p.h"
|
||||||
|
|
||||||
|
#include "imapparser_p.h"
|
||||||
|
|
||||||
|
#include <QtCore/QSharedData>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
class ImapInterval::Private : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Private()
|
||||||
|
: QSharedData()
|
||||||
|
, begin( 0 )
|
||||||
|
, end( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Private( const Private &other )
|
||||||
|
: QSharedData( other )
|
||||||
|
{
|
||||||
|
begin = other.begin;
|
||||||
|
end = other.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
Id begin;
|
||||||
|
Id end;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImapSet::Private : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Private()
|
||||||
|
: QSharedData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Private( const Private &other )
|
||||||
|
: QSharedData( other )
|
||||||
|
{
|
||||||
|
intervals = other.intervals;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapInterval::List intervals;
|
||||||
|
};
|
||||||
|
|
||||||
|
ImapInterval::ImapInterval()
|
||||||
|
: d( new Private )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapInterval::ImapInterval( const ImapInterval &other )
|
||||||
|
: d( other.d )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapInterval::ImapInterval( Id begin, Id end )
|
||||||
|
: d( new Private )
|
||||||
|
{
|
||||||
|
d->begin = begin;
|
||||||
|
d->end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapInterval::~ImapInterval()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapInterval &ImapInterval::operator=( const ImapInterval &other )
|
||||||
|
{
|
||||||
|
if ( this != &other ) {
|
||||||
|
d = other.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImapInterval::operator==( const ImapInterval &other ) const
|
||||||
|
{
|
||||||
|
return ( d->begin == other.d->begin && d->end == other.d->end );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapInterval::Id ImapInterval::size() const
|
||||||
|
{
|
||||||
|
if ( !d->begin && !d->end ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( d->end - d->begin + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImapInterval::hasDefinedBegin() const
|
||||||
|
{
|
||||||
|
return ( d->begin != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapInterval::Id ImapInterval::begin() const
|
||||||
|
{
|
||||||
|
return d->begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImapInterval::hasDefinedEnd() const
|
||||||
|
{
|
||||||
|
return ( d->end != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapInterval::Id ImapInterval::end() const
|
||||||
|
{
|
||||||
|
if ( hasDefinedEnd() ) {
|
||||||
|
return d->end;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::numeric_limits<Id>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImapInterval::setBegin( Id value )
|
||||||
|
{
|
||||||
|
Q_ASSERT( value >= 0 );
|
||||||
|
Q_ASSERT( value <= d->end || !hasDefinedEnd() );
|
||||||
|
d->begin = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImapInterval::setEnd( Id value )
|
||||||
|
{
|
||||||
|
Q_ASSERT( value >= 0 );
|
||||||
|
Q_ASSERT( value >= d->begin || !hasDefinedBegin() );
|
||||||
|
d->end = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Akonadi::ImapInterval::toImapSequence() const
|
||||||
|
{
|
||||||
|
if ( size() == 0 ) {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( size() == 1 ) {
|
||||||
|
return QByteArray::number( d->begin );
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray rv;
|
||||||
|
rv += QByteArray::number( d->begin ) + ':';
|
||||||
|
|
||||||
|
if ( hasDefinedEnd() ) {
|
||||||
|
rv += QByteArray::number( d->end );
|
||||||
|
} else {
|
||||||
|
rv += '*';
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapSet::ImapSet()
|
||||||
|
: d( new Private )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapSet::ImapSet( const ImapSet &other )
|
||||||
|
: d( other.d )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapSet::~ImapSet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapSet &ImapSet::operator=( const ImapSet &other )
|
||||||
|
{
|
||||||
|
if ( this != &other ) {
|
||||||
|
d = other.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImapSet::add( const QList<Id> &values )
|
||||||
|
{
|
||||||
|
add( values.toVector() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImapSet::add( const QVector<Id> &values )
|
||||||
|
{
|
||||||
|
QVector<Id> vals = values;
|
||||||
|
qSort( vals );
|
||||||
|
for ( int i = 0; i < vals.count(); ++i ) {
|
||||||
|
const int begin = vals[i];
|
||||||
|
Q_ASSERT( begin >= 0 );
|
||||||
|
if ( i == vals.count() - 1 ) {
|
||||||
|
d->intervals << ImapInterval( begin, begin );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
++i;
|
||||||
|
Q_ASSERT( vals[i] >= 0 );
|
||||||
|
if ( vals[i] != ( vals[i - 1] + 1 ) ) {
|
||||||
|
--i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ( i < vals.count() - 1 );
|
||||||
|
d->intervals << ImapInterval( begin, vals[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImapSet::add( const QSet<Id> &values )
|
||||||
|
{
|
||||||
|
QVector<Id> v;
|
||||||
|
v.reserve( values.size() );
|
||||||
|
for ( QSet<Id>::ConstIterator iter = values.constBegin(); iter != values.constEnd(); ++iter ) {
|
||||||
|
v.push_back( *iter );
|
||||||
|
}
|
||||||
|
|
||||||
|
add( v );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ImapSet::add( const ImapInterval &interval )
|
||||||
|
{
|
||||||
|
d->intervals << interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ImapSet::toImapSequenceSet() const
|
||||||
|
{
|
||||||
|
QList<QByteArray> rv;
|
||||||
|
Q_FOREACH ( const ImapInterval &interval, d->intervals ) {
|
||||||
|
rv << interval.toImapSequence();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImapParser::join( rv, "," );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImapInterval::List ImapSet::intervals() const
|
||||||
|
{
|
||||||
|
return d->intervals;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImapSet::isEmpty() const
|
||||||
|
{
|
||||||
|
return d->intervals.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug &operator<<( QDebug &d, const Akonadi::ImapInterval &interval )
|
||||||
|
{
|
||||||
|
d << interval.toImapSequence();
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<( QDebug d, const Akonadi::ImapSet &set )
|
||||||
|
{
|
||||||
|
d << set.toImapSequenceSet();
|
||||||
|
return d;
|
||||||
|
}
|
220
akonadi/libs/imapset_p.h
Normal file
220
akonadi/libs/imapset_p.h
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_IMAPSET_P_H
|
||||||
|
#define AKONADI_IMAPSET_P_H
|
||||||
|
|
||||||
|
#include "akonadiprotocolinternals_export.h"
|
||||||
|
|
||||||
|
#include <QtCore/QByteArray>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QMetaType>
|
||||||
|
#include <QtCore/QSharedDataPointer>
|
||||||
|
|
||||||
|
namespace Akonadi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Represents a single interval in an ImapSet.
|
||||||
|
This class is implicitly shared.
|
||||||
|
*/
|
||||||
|
class AKONADIPROTOCOLINTERNALS_EXPORT ImapInterval
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Describes the ids stored in the interval.
|
||||||
|
*/
|
||||||
|
typedef qint64 Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A list of ImapInterval objects.
|
||||||
|
*/
|
||||||
|
typedef QList<ImapInterval> List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constructs an interval that covers all positive numbers.
|
||||||
|
*/
|
||||||
|
ImapInterval();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Copy constructor.
|
||||||
|
*/
|
||||||
|
ImapInterval( const ImapInterval &other );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a new interval.
|
||||||
|
@param begin The begin of the interval.
|
||||||
|
@param end Keep default (0) to just set the interval begin
|
||||||
|
*/
|
||||||
|
explicit ImapInterval( Id begin, Id end = 0 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destructor.
|
||||||
|
*/
|
||||||
|
~ImapInterval();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Assignment operator.
|
||||||
|
*/
|
||||||
|
ImapInterval &operator=( const ImapInterval &other );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Comparison operator.
|
||||||
|
*/
|
||||||
|
bool operator==( const ImapInterval &other ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the size of this interval.
|
||||||
|
Size is only defined for finite intervals.
|
||||||
|
*/
|
||||||
|
Id size() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns true if this interval has a defined begin.
|
||||||
|
*/
|
||||||
|
bool hasDefinedBegin() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the begin of this interval. The value is the smallest value part of the interval.
|
||||||
|
Only valid if begin is defined.
|
||||||
|
*/
|
||||||
|
Id begin() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns true if this intercal has been defined.
|
||||||
|
*/
|
||||||
|
bool hasDefinedEnd() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the end of this interval. This value is the largest value part of the interval.
|
||||||
|
Only valid if hasDefinedEnd() returned true.
|
||||||
|
*/
|
||||||
|
Id end() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the begin of the interval.
|
||||||
|
*/
|
||||||
|
void setBegin( Id value );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the end of this interval.
|
||||||
|
*/
|
||||||
|
void setEnd( Id value );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Converts this set into an IMAP compatible sequence.
|
||||||
|
*/
|
||||||
|
QByteArray toImapSequence() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Private;
|
||||||
|
QSharedDataPointer<Private> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Represents a set of natural numbers (1->\f$\infty\f$) in a as compact as possible form.
|
||||||
|
Used to address Akonadi items via the IMAP protocol or in the database.
|
||||||
|
This class is implicitly shared.
|
||||||
|
*/
|
||||||
|
class AKONADIPROTOCOLINTERNALS_EXPORT ImapSet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Describes the ids stored in the set.
|
||||||
|
*/
|
||||||
|
typedef qint64 Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constructs an empty set.
|
||||||
|
*/
|
||||||
|
ImapSet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Copy constructor.
|
||||||
|
*/
|
||||||
|
ImapSet( const ImapSet &other );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destructor.
|
||||||
|
*/
|
||||||
|
~ImapSet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Assignment operator.
|
||||||
|
*/
|
||||||
|
ImapSet &operator=( const ImapSet &other );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds the given list of positive integer numbers to the set.
|
||||||
|
The list is sorted and split into as large as possible intervals.
|
||||||
|
No interval merging is performed.
|
||||||
|
@param values List of positive integer numbers in arbitrary order
|
||||||
|
*/
|
||||||
|
void add( const QVector<Id> &values );
|
||||||
|
|
||||||
|
/**
|
||||||
|
@overload
|
||||||
|
@deprecated Use the QVector version instead.
|
||||||
|
*/
|
||||||
|
void add( const QList<Id> &values );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
*/
|
||||||
|
void add( const QSet<Id> &values );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds the given ImapInterval to this set.
|
||||||
|
No interval merging is performed.
|
||||||
|
*/
|
||||||
|
void add( const ImapInterval &interval );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a IMAP-compatible QByteArray representation of this set.
|
||||||
|
*/
|
||||||
|
QByteArray toImapSequenceSet() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the intervals this set consists of.
|
||||||
|
*/
|
||||||
|
ImapInterval::List intervals() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns true if this set doesn't contains any values.
|
||||||
|
*/
|
||||||
|
bool isEmpty() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Private;
|
||||||
|
QSharedDataPointer<Private> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AKONADIPROTOCOLINTERNALS_EXPORT QDebug &operator<<( QDebug &d, const Akonadi::ImapInterval &interval );
|
||||||
|
AKONADIPROTOCOLINTERNALS_EXPORT QDebug operator<<( QDebug d, const Akonadi::ImapSet &set );
|
||||||
|
|
||||||
|
Q_DECLARE_TYPEINFO( Akonadi::ImapInterval, Q_MOVABLE_TYPE );
|
||||||
|
Q_DECLARE_TYPEINFO( Akonadi::ImapSet, Q_MOVABLE_TYPE );
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::ImapInterval )
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::ImapInterval::List )
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::ImapSet )
|
||||||
|
|
||||||
|
#endif
|
432
akonadi/libs/notificationmessage.cpp
Normal file
432
akonadi/libs/notificationmessage.cpp
Normal file
|
@ -0,0 +1,432 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "notificationmessage_p.h"
|
||||||
|
#include "imapparser_p.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QHash>
|
||||||
|
#include <QtDBus/QDBusMetaType>
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
class NotificationMessage::Private : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Private()
|
||||||
|
: QSharedData()
|
||||||
|
, type( NotificationMessage::InvalidType )
|
||||||
|
, operation( NotificationMessage::InvalidOp )
|
||||||
|
, uid( -1 )
|
||||||
|
, parentCollection( -1 )
|
||||||
|
, parentDestCollection( -1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Private( const Private &other )
|
||||||
|
: QSharedData( other )
|
||||||
|
{
|
||||||
|
sessionId = other.sessionId;
|
||||||
|
type = other.type;
|
||||||
|
operation = other.operation;
|
||||||
|
uid = other.uid;
|
||||||
|
remoteId = other.remoteId;
|
||||||
|
resource = other.resource;
|
||||||
|
destResource = other.destResource;
|
||||||
|
parentCollection = other.parentCollection;
|
||||||
|
parentDestCollection = other.parentDestCollection;
|
||||||
|
mimeType = other.mimeType;
|
||||||
|
parts = other.parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compareWithoutOpAndParts( const Private &other ) const
|
||||||
|
{
|
||||||
|
return uid == other.uid
|
||||||
|
&& type == other.type
|
||||||
|
&& sessionId == other.sessionId
|
||||||
|
&& remoteId == other.remoteId
|
||||||
|
&& resource == other.resource
|
||||||
|
&& destResource == other.destResource
|
||||||
|
&& parentCollection == other.parentCollection
|
||||||
|
&& parentDestCollection == other.parentDestCollection
|
||||||
|
&& mimeType == other.mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==( const Private &other ) const
|
||||||
|
{
|
||||||
|
return operation == other.operation && parts == other.parts && compareWithoutOpAndParts( other );
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray sessionId;
|
||||||
|
NotificationMessage::Type type;
|
||||||
|
NotificationMessage::Operation operation;
|
||||||
|
Id uid;
|
||||||
|
QString remoteId;
|
||||||
|
QByteArray resource;
|
||||||
|
QByteArray destResource;
|
||||||
|
Id parentCollection;
|
||||||
|
Id parentDestCollection;
|
||||||
|
QString mimeType;
|
||||||
|
QSet<QByteArray> parts;
|
||||||
|
};
|
||||||
|
|
||||||
|
NotificationMessage::NotificationMessage()
|
||||||
|
: d( new Private )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessage::NotificationMessage( const NotificationMessage &other )
|
||||||
|
: d( other.d )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessage::~NotificationMessage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessage &NotificationMessage::operator=( const NotificationMessage &other )
|
||||||
|
{
|
||||||
|
if ( this != &other ) {
|
||||||
|
d = other.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotificationMessage::operator==( const NotificationMessage &other ) const
|
||||||
|
{
|
||||||
|
return d == other.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::registerDBusTypes()
|
||||||
|
{
|
||||||
|
qDBusRegisterMetaType<Akonadi::NotificationMessage>();
|
||||||
|
qDBusRegisterMetaType<Akonadi::NotificationMessage::List>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NotificationMessage::sessionId() const
|
||||||
|
{
|
||||||
|
return d->sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setSessionId( const QByteArray &sessionId )
|
||||||
|
{
|
||||||
|
d->sessionId = sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessage::Type NotificationMessage::type() const
|
||||||
|
{
|
||||||
|
return d->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setType( Type type )
|
||||||
|
{
|
||||||
|
d->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessage::Operation NotificationMessage::operation() const
|
||||||
|
{
|
||||||
|
return d->operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setOperation( Operation operation )
|
||||||
|
{
|
||||||
|
d->operation = operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessage::Id NotificationMessage::uid() const
|
||||||
|
{
|
||||||
|
return d->uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setUid( Id uid )
|
||||||
|
{
|
||||||
|
d->uid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NotificationMessage::remoteId() const
|
||||||
|
{
|
||||||
|
return d->remoteId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setRemoteId( const QString &remoteId )
|
||||||
|
{
|
||||||
|
d->remoteId = remoteId;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NotificationMessage::resource() const
|
||||||
|
{
|
||||||
|
return d->resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setResource( const QByteArray &resource )
|
||||||
|
{
|
||||||
|
d->resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessage::Id NotificationMessage::parentCollection() const
|
||||||
|
{
|
||||||
|
return d->parentCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessage::Id NotificationMessage::parentDestCollection() const
|
||||||
|
{
|
||||||
|
return d->parentDestCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setParentCollection( Id parent )
|
||||||
|
{
|
||||||
|
d->parentCollection = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setParentDestCollection( Id parent )
|
||||||
|
{
|
||||||
|
d->parentDestCollection = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setDestinationResource( const QByteArray &destResource )
|
||||||
|
{
|
||||||
|
d->destResource = destResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NotificationMessage::destinationResource() const
|
||||||
|
{
|
||||||
|
return d->destResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NotificationMessage::mimeType() const
|
||||||
|
{
|
||||||
|
return d->mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setMimeType( const QString &mimeType )
|
||||||
|
{
|
||||||
|
d->mimeType = mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<QByteArray> NotificationMessage::itemParts() const
|
||||||
|
{
|
||||||
|
return d->parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::setItemParts( const QSet<QByteArray> &parts )
|
||||||
|
{
|
||||||
|
d->parts = parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NotificationMessage::toString() const
|
||||||
|
{
|
||||||
|
QString rv;
|
||||||
|
// some tests before making the string
|
||||||
|
if ( type() == InvalidType ) {
|
||||||
|
return QLatin1String( "Error: Type is not set" );
|
||||||
|
}
|
||||||
|
if ( uid() == -1 ) {
|
||||||
|
return QLatin1String( "Error: uid is not set" );
|
||||||
|
}
|
||||||
|
if ( remoteId().isEmpty() ) {
|
||||||
|
return QLatin1String( "Error: remoteId is empty" );
|
||||||
|
}
|
||||||
|
if ( operation() == InvalidOp ) {
|
||||||
|
return QLatin1String( "Error: operation is not set" );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( type() ) {
|
||||||
|
case Item:
|
||||||
|
rv += QLatin1String( "Item " );
|
||||||
|
break;
|
||||||
|
case Collection:
|
||||||
|
rv += QLatin1String( "Collection " );
|
||||||
|
break;
|
||||||
|
case InvalidType:
|
||||||
|
// already done above
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv += QString::fromLatin1( "(%1, %2) " ).arg( uid() ).arg( remoteId() );
|
||||||
|
|
||||||
|
if ( parentCollection() >= 0 ) {
|
||||||
|
if ( parentDestCollection() >= 0 ) {
|
||||||
|
rv += QString::fromLatin1( "from " );
|
||||||
|
} else {
|
||||||
|
rv += QString::fromLatin1( "in " );
|
||||||
|
}
|
||||||
|
rv += QString::fromLatin1( "collection %1 " ).arg( parentCollection() );
|
||||||
|
} else {
|
||||||
|
rv += QLatin1String( "unspecified parent collection " );
|
||||||
|
}
|
||||||
|
|
||||||
|
rv += QString::fromLatin1( "mimetype %1 " ).arg( mimeType().isEmpty() ? QLatin1String( "unknown" ) : mimeType() );
|
||||||
|
|
||||||
|
switch ( operation() ) {
|
||||||
|
case Add:
|
||||||
|
rv += QLatin1String( "added" );
|
||||||
|
break;
|
||||||
|
case Modify:
|
||||||
|
rv += QLatin1String( "modified parts (" );
|
||||||
|
rv += QString::fromLatin1( ImapParser::join( itemParts().toList(), ", " ) );
|
||||||
|
rv += QLatin1String( ")" );
|
||||||
|
break;
|
||||||
|
case Move:
|
||||||
|
rv += QLatin1String( "moved" );
|
||||||
|
break;
|
||||||
|
case Remove:
|
||||||
|
rv += QLatin1String( "removed" );
|
||||||
|
break;
|
||||||
|
case Link:
|
||||||
|
rv += QLatin1String( "linked" );
|
||||||
|
break;
|
||||||
|
case Unlink:
|
||||||
|
rv += QLatin1String( "unlinked" );
|
||||||
|
break;
|
||||||
|
case Subscribe:
|
||||||
|
rv += QLatin1String( "subscribed" );
|
||||||
|
break;
|
||||||
|
case Unsubscribe:
|
||||||
|
rv += QLatin1String( "unsubscribed" );
|
||||||
|
break;
|
||||||
|
case InvalidOp:
|
||||||
|
// already done above
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( parentDestCollection() >= 0 ) {
|
||||||
|
rv += QString::fromLatin1( " to collection %1" ).arg( parentDestCollection() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::appendAndCompress( NotificationMessage::List &list, const NotificationMessage &msg )
|
||||||
|
{
|
||||||
|
bool appended;
|
||||||
|
appendAndCompress( list, msg, &appended );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessage::appendAndCompress( NotificationMessage::List &list, const NotificationMessage &msg, bool *appended )
|
||||||
|
{
|
||||||
|
// fast-path for stuff that is not considered during O(n) compression below
|
||||||
|
if ( msg.operation() != Add && msg.operation() != Link && msg.operation() != Unlink && msg.operation() != Subscribe && msg.operation() != Unsubscribe && msg.operation() != Move ) {
|
||||||
|
NotificationMessage::List::Iterator end = list.end();
|
||||||
|
for ( NotificationMessage::List::Iterator it = list.begin(); it != end; ) {
|
||||||
|
if ( msg.d.constData()->compareWithoutOpAndParts( *( ( *it ).d.constData() ) ) ) {
|
||||||
|
// same operation: merge changed parts and drop the new one
|
||||||
|
if ( msg.operation() == ( *it ).operation() ) {
|
||||||
|
( *it ).setItemParts( ( *it ).itemParts() + msg.itemParts() );
|
||||||
|
*appended = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// new one is a modification, the existing one not, so drop the new one
|
||||||
|
else if ( msg.operation() == Modify ) {
|
||||||
|
*appended = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// new on is a deletion, erase the existing modification ones (and keep going, in case there are more)
|
||||||
|
else if ( msg.operation() == Remove && ( *it ).operation() == Modify ) {
|
||||||
|
it = list.erase( it );
|
||||||
|
end = list.end();
|
||||||
|
}
|
||||||
|
// keep looking
|
||||||
|
else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*appended = true;
|
||||||
|
list.append( msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &arg, const NotificationMessage &msg )
|
||||||
|
{
|
||||||
|
arg.beginStructure();
|
||||||
|
arg << msg.sessionId();
|
||||||
|
arg << msg.type();
|
||||||
|
arg << msg.operation();
|
||||||
|
arg << msg.uid();
|
||||||
|
arg << msg.remoteId();
|
||||||
|
arg << msg.resource();
|
||||||
|
arg << msg.parentCollection();
|
||||||
|
arg << msg.parentDestCollection();
|
||||||
|
arg << msg.mimeType();
|
||||||
|
|
||||||
|
QStringList itemParts;
|
||||||
|
if ( msg.operation() == NotificationMessage::Move ) {
|
||||||
|
// encode destination resource in parts, as a backward compat hack
|
||||||
|
itemParts.push_back( QString::fromLatin1( msg.destinationResource() ) );
|
||||||
|
} else {
|
||||||
|
Q_FOREACH ( const QByteArray &itemPart, msg.itemParts() ) {
|
||||||
|
itemParts.append( QString::fromLatin1( itemPart ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arg << itemParts;
|
||||||
|
arg.endStructure();
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, NotificationMessage &msg )
|
||||||
|
{
|
||||||
|
arg.beginStructure();
|
||||||
|
QByteArray b;
|
||||||
|
arg >> b;
|
||||||
|
msg.setSessionId( b );
|
||||||
|
int i;
|
||||||
|
arg >> i;
|
||||||
|
msg.setType( static_cast<NotificationMessage::Type>( i ) );
|
||||||
|
arg >> i;
|
||||||
|
msg.setOperation( static_cast<NotificationMessage::Operation>( i ) );
|
||||||
|
NotificationMessage::Id id;
|
||||||
|
arg >> id;
|
||||||
|
msg.setUid( id );
|
||||||
|
QString s;
|
||||||
|
arg >> s;
|
||||||
|
msg.setRemoteId( s );
|
||||||
|
arg >> b;
|
||||||
|
msg.setResource( b );
|
||||||
|
arg >> id;
|
||||||
|
msg.setParentCollection( id );
|
||||||
|
arg >> id;
|
||||||
|
msg.setParentDestCollection( id );
|
||||||
|
arg >> s;
|
||||||
|
msg.setMimeType( s );
|
||||||
|
QStringList l;
|
||||||
|
arg >> l;
|
||||||
|
|
||||||
|
QSet<QByteArray> itemParts;
|
||||||
|
if ( msg.operation() == NotificationMessage::Move && l.size() >= 1 ) {
|
||||||
|
// decode destination resource, which is stored in parts as a backward compat hack
|
||||||
|
msg.setDestinationResource( l.first().toLatin1() );
|
||||||
|
} else {
|
||||||
|
Q_FOREACH ( const QString &itemPart, l ) {
|
||||||
|
itemParts.insert( itemPart.toLatin1() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.setItemParts( itemParts );
|
||||||
|
arg.endStructure();
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint qHash( const Akonadi::NotificationMessage &msg )
|
||||||
|
{
|
||||||
|
return qHash( msg.uid() + ( msg.type() << 31 ) + ( msg.operation() << 28 ) );
|
||||||
|
}
|
136
akonadi/libs/notificationmessage_p.h
Normal file
136
akonadi/libs/notificationmessage_p.h
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_NOTIFICATIONMESSAGE_P_H
|
||||||
|
#define AKONADI_NOTIFICATIONMESSAGE_P_H
|
||||||
|
|
||||||
|
#include "akonadiprotocolinternals_export.h"
|
||||||
|
|
||||||
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QMetaType>
|
||||||
|
#include <QtCore/QSharedDataPointer>
|
||||||
|
#include <QtDBus/QDBusArgument>
|
||||||
|
|
||||||
|
namespace Akonadi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
@internal
|
||||||
|
Used for sending notification signals over DBus.
|
||||||
|
DBus type: (ayiiisayisas)
|
||||||
|
*/
|
||||||
|
|
||||||
|
class AKONADIPROTOCOLINTERNALS_EXPORT NotificationMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef QList<NotificationMessage> List;
|
||||||
|
typedef qint64 Id;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
InvalidType,
|
||||||
|
Collection,
|
||||||
|
Item
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Operation {
|
||||||
|
InvalidOp,
|
||||||
|
Add,
|
||||||
|
Modify,
|
||||||
|
Move,
|
||||||
|
Remove,
|
||||||
|
Link,
|
||||||
|
Unlink,
|
||||||
|
Subscribe,
|
||||||
|
Unsubscribe
|
||||||
|
};
|
||||||
|
|
||||||
|
NotificationMessage();
|
||||||
|
NotificationMessage( const NotificationMessage &other );
|
||||||
|
~NotificationMessage();
|
||||||
|
|
||||||
|
NotificationMessage &operator=( const NotificationMessage &other );
|
||||||
|
bool operator==( const NotificationMessage &other ) const;
|
||||||
|
|
||||||
|
static void registerDBusTypes();
|
||||||
|
|
||||||
|
QByteArray sessionId() const;
|
||||||
|
void setSessionId( const QByteArray &sessionId );
|
||||||
|
|
||||||
|
Type type() const;
|
||||||
|
void setType( Type type );
|
||||||
|
|
||||||
|
Operation operation() const;
|
||||||
|
void setOperation( Operation operation );
|
||||||
|
|
||||||
|
Id uid() const;
|
||||||
|
void setUid( Id uid );
|
||||||
|
|
||||||
|
QString remoteId() const;
|
||||||
|
void setRemoteId( const QString &remoteId );
|
||||||
|
|
||||||
|
QByteArray resource() const;
|
||||||
|
void setResource( const QByteArray &resource );
|
||||||
|
|
||||||
|
Id parentCollection() const;
|
||||||
|
void setParentCollection( Id parent );
|
||||||
|
|
||||||
|
Id parentDestCollection() const;
|
||||||
|
void setParentDestCollection( Id parent );
|
||||||
|
|
||||||
|
QByteArray destinationResource() const;
|
||||||
|
void setDestinationResource( const QByteArray &destResource );
|
||||||
|
|
||||||
|
QString mimeType() const;
|
||||||
|
void setMimeType( const QString &mimeType );
|
||||||
|
|
||||||
|
QSet<QByteArray> itemParts() const;
|
||||||
|
void setItemParts( const QSet<QByteArray> &parts );
|
||||||
|
|
||||||
|
QString toString() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds a new notification message to the given list and compresses notifications
|
||||||
|
where possible.
|
||||||
|
*/
|
||||||
|
static void appendAndCompress( NotificationMessage::List &list, const NotificationMessage &msg );
|
||||||
|
// BIC: make the above return bool.
|
||||||
|
static void appendAndCompress( NotificationMessage::List &list, const NotificationMessage &msg, bool *appended );
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Private;
|
||||||
|
QSharedDataPointer<Private> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &arg, const Akonadi::NotificationMessage &msg );
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, Akonadi::NotificationMessage &msg );
|
||||||
|
|
||||||
|
uint qHash( const Akonadi::NotificationMessage &msg );
|
||||||
|
|
||||||
|
Q_DECLARE_TYPEINFO( Akonadi::NotificationMessage, Q_MOVABLE_TYPE );
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::NotificationMessage )
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::NotificationMessage::List )
|
||||||
|
|
||||||
|
// V2 is used in NotificationSource.xml interface, so it must be
|
||||||
|
// defined so that old clients that only include this header
|
||||||
|
// will compile
|
||||||
|
#include "notificationmessagev2_p.h"
|
||||||
|
|
||||||
|
#endif
|
585
akonadi/libs/notificationmessagev2.cpp
Normal file
585
akonadi/libs/notificationmessagev2.cpp
Normal file
|
@ -0,0 +1,585 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
Copyright (c) 2013 Daniel Vrátil <dvratil@redhat.com>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "notificationmessagev2_p.h"
|
||||||
|
#include "notificationmessagev2_p_p.h"
|
||||||
|
#include "notificationmessage_p.h"
|
||||||
|
#include "imapparser_p.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QHash>
|
||||||
|
#include <QtDBus/QDBusMetaType>
|
||||||
|
#include <qdbusconnection.h>
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
class NotificationMessageV2::Private : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Private()
|
||||||
|
: QSharedData()
|
||||||
|
, type( InvalidType )
|
||||||
|
, operation( InvalidOp )
|
||||||
|
, parentCollection( -1 )
|
||||||
|
, parentDestCollection( -1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Private( const Private &other )
|
||||||
|
: QSharedData( other )
|
||||||
|
{
|
||||||
|
sessionId = other.sessionId;
|
||||||
|
type = other.type;
|
||||||
|
operation = other.operation;
|
||||||
|
items = other.items;
|
||||||
|
resource = other.resource;
|
||||||
|
destResource = other.destResource;
|
||||||
|
parentCollection = other.parentCollection;
|
||||||
|
parentDestCollection = other.parentDestCollection;
|
||||||
|
parts = other.parts;
|
||||||
|
addedFlags = other.addedFlags;
|
||||||
|
removedFlags = other.removedFlags;
|
||||||
|
addedTags = other.addedTags;
|
||||||
|
removedTags = other.removedTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray sessionId;
|
||||||
|
NotificationMessageV2::Type type;
|
||||||
|
NotificationMessageV2::Operation operation;
|
||||||
|
QMap<Id, NotificationMessageV2::Entity> items;
|
||||||
|
QByteArray resource;
|
||||||
|
QByteArray destResource;
|
||||||
|
Id parentCollection;
|
||||||
|
Id parentDestCollection;
|
||||||
|
QSet<QByteArray> parts;
|
||||||
|
QSet<QByteArray> addedFlags;
|
||||||
|
QSet<QByteArray> removedFlags;
|
||||||
|
QSet<qint64> addedTags;
|
||||||
|
QSet<qint64> removedTags;
|
||||||
|
};
|
||||||
|
|
||||||
|
NotificationMessageV2::NotificationMessageV2():
|
||||||
|
d( new Private )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV2::NotificationMessageV2( const NotificationMessageV2 &other ):
|
||||||
|
d( other.d )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV2::~NotificationMessageV2()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV2 &NotificationMessageV2::operator=( const NotificationMessageV2 &other )
|
||||||
|
{
|
||||||
|
if ( this != &other ) {
|
||||||
|
d = other.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotificationMessageV2::operator==( const NotificationMessageV2 &other ) const
|
||||||
|
{
|
||||||
|
return d->operation == other.d->operation
|
||||||
|
&& d->parts == other.d->parts
|
||||||
|
&& d->addedFlags == other.d->addedFlags
|
||||||
|
&& d->removedFlags == other.d->removedFlags
|
||||||
|
&& d->addedTags == other.d->addedTags
|
||||||
|
&& d->removedTags == other.d->removedTags
|
||||||
|
&& NotificationMessageHelpers::compareWithoutOpAndParts( *this, other );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::registerDBusTypes()
|
||||||
|
{
|
||||||
|
qDBusRegisterMetaType<Akonadi::NotificationMessageV2>();
|
||||||
|
qDBusRegisterMetaType<Akonadi::NotificationMessageV2::Entity>();
|
||||||
|
qDBusRegisterMetaType<Akonadi::NotificationMessageV2::List>();
|
||||||
|
qDBusRegisterMetaType<Akonadi::NotificationMessageV2::Type>();
|
||||||
|
qDBusRegisterMetaType<QVector<QByteArray> >();
|
||||||
|
qDBusRegisterMetaType<QVector<qint64> >();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotificationMessageV2::isValid() const
|
||||||
|
{
|
||||||
|
return d->operation != Akonadi::NotificationMessageV2::InvalidOp
|
||||||
|
&& d->type != Akonadi::NotificationMessageV2::InvalidType
|
||||||
|
&& !d->items.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::addEntity( Id id, const QString &remoteId, const QString &remoteRevision, const QString &mimeType )
|
||||||
|
{
|
||||||
|
NotificationMessageV2::Entity item;
|
||||||
|
item.id = id;
|
||||||
|
item.remoteId = remoteId;
|
||||||
|
item.remoteRevision = remoteRevision;
|
||||||
|
item.mimeType = mimeType;
|
||||||
|
|
||||||
|
d->items.insert( id, item );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setEntities( const QList<NotificationMessageV2::Entity> &items )
|
||||||
|
{
|
||||||
|
clearEntities();
|
||||||
|
Q_FOREACH ( const NotificationMessageV2::Entity &item, items ) {
|
||||||
|
d->items.insert( item.id, item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::clearEntities()
|
||||||
|
{
|
||||||
|
d->items.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<NotificationMessageV2::Id, NotificationMessageV2::Entity> NotificationMessageV2::entities() const
|
||||||
|
{
|
||||||
|
return d->items;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV2::Entity NotificationMessageV2::entity( NotificationMessageV2::Id id ) const
|
||||||
|
{
|
||||||
|
return d->items.value( id );
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<NotificationMessageV2::Id> NotificationMessageV2::uids() const
|
||||||
|
{
|
||||||
|
return d->items.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NotificationMessageV2::sessionId() const
|
||||||
|
{
|
||||||
|
return d->sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setSessionId( const QByteArray &sessionId )
|
||||||
|
{
|
||||||
|
d->sessionId = sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV2::Type NotificationMessageV2::type() const
|
||||||
|
{
|
||||||
|
return d->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setType( Type type )
|
||||||
|
{
|
||||||
|
d->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV2::Operation NotificationMessageV2::operation() const
|
||||||
|
{
|
||||||
|
return d->operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setOperation( Operation operation )
|
||||||
|
{
|
||||||
|
d->operation = operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NotificationMessageV2::resource() const
|
||||||
|
{
|
||||||
|
return d->resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setResource( const QByteArray &resource )
|
||||||
|
{
|
||||||
|
d->resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV2::Id NotificationMessageV2::parentCollection() const
|
||||||
|
{
|
||||||
|
return d->parentCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV2::Id NotificationMessageV2::parentDestCollection() const
|
||||||
|
{
|
||||||
|
return d->parentDestCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setParentCollection( Id parent )
|
||||||
|
{
|
||||||
|
d->parentCollection = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setParentDestCollection( Id parent )
|
||||||
|
{
|
||||||
|
d->parentDestCollection = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setDestinationResource( const QByteArray &destResource )
|
||||||
|
{
|
||||||
|
d->destResource = destResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NotificationMessageV2::destinationResource() const
|
||||||
|
{
|
||||||
|
return d->destResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<QByteArray> NotificationMessageV2::itemParts() const
|
||||||
|
{
|
||||||
|
return d->parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setItemParts( const QSet<QByteArray> &parts )
|
||||||
|
{
|
||||||
|
d->parts = parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<QByteArray> NotificationMessageV2::addedFlags() const
|
||||||
|
{
|
||||||
|
return d->addedFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setAddedFlags( const QSet<QByteArray> &addedFlags )
|
||||||
|
{
|
||||||
|
d->addedFlags = addedFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<QByteArray> NotificationMessageV2::removedFlags() const
|
||||||
|
{
|
||||||
|
return d->removedFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setRemovedFlags( const QSet<QByteArray> &removedFlags )
|
||||||
|
{
|
||||||
|
d->removedFlags = removedFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<qint64> NotificationMessageV2::addedTags() const
|
||||||
|
{
|
||||||
|
return d->addedTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setAddedTags( const QSet<qint64> &addedTags )
|
||||||
|
{
|
||||||
|
d->addedTags = addedTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<qint64> NotificationMessageV2::removedTags() const
|
||||||
|
{
|
||||||
|
return d->removedTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2::setRemovedTags( const QSet<qint64> &removedTags )
|
||||||
|
{
|
||||||
|
d->removedTags = removedTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString NotificationMessageV2::toString() const
|
||||||
|
{
|
||||||
|
QString rv;
|
||||||
|
|
||||||
|
switch ( d->type ) {
|
||||||
|
case Items:
|
||||||
|
rv += QLatin1String( "Items " );
|
||||||
|
break;
|
||||||
|
case Collections:
|
||||||
|
rv += QLatin1String( "Collections " );
|
||||||
|
break;
|
||||||
|
case Tags:
|
||||||
|
rv += QLatin1String( "Tags " );
|
||||||
|
break;
|
||||||
|
case InvalidType:
|
||||||
|
return QLatin1String( "*INVALID TYPE* " );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<QByteArray> items;
|
||||||
|
Q_FOREACH ( const NotificationMessageV2::Entity &item, d->items ) {
|
||||||
|
QString itemStr = QString::fromLatin1( "(%1,%2" ).arg( item.id ).arg( item.remoteId );
|
||||||
|
if ( !item.remoteRevision.isEmpty() ) {
|
||||||
|
itemStr += QString::fromLatin1( ",%1" ).arg( item.remoteRevision );
|
||||||
|
}
|
||||||
|
if ( !item.mimeType.isEmpty() ) {
|
||||||
|
itemStr += QString::fromLatin1( ",%1" ).arg( item.mimeType );
|
||||||
|
}
|
||||||
|
itemStr += QLatin1String( ")" );
|
||||||
|
items << itemStr.toLatin1();
|
||||||
|
}
|
||||||
|
rv += QLatin1String( "(" ) + QString::fromLatin1( ImapParser::join( items, ", " ) ) + QLatin1String( ")" );
|
||||||
|
|
||||||
|
if ( d->parentDestCollection >= 0 ) {
|
||||||
|
rv += QLatin1String( " from " );
|
||||||
|
} else {
|
||||||
|
rv += QLatin1String( " in " );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( d->parentCollection >= 0 ) {
|
||||||
|
rv += QString::fromLatin1( "collection %1 " ).arg( d->parentCollection );
|
||||||
|
} else {
|
||||||
|
rv += QLatin1String( "unspecified parent collection " );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( d->operation ) {
|
||||||
|
case Add:
|
||||||
|
rv += QLatin1String( "added" );
|
||||||
|
break;
|
||||||
|
case Modify:
|
||||||
|
rv += QLatin1String( "modified parts (" );
|
||||||
|
rv += QString::fromLatin1( ImapParser::join( d->parts.toList(), ", " ) );
|
||||||
|
rv += QLatin1String( ")" );
|
||||||
|
break;
|
||||||
|
case ModifyFlags:
|
||||||
|
rv += QLatin1String( "added flags (" );
|
||||||
|
rv += QString::fromLatin1( ImapParser::join( d->addedFlags.toList(), ", " ) );
|
||||||
|
rv += QLatin1String( ") " );
|
||||||
|
|
||||||
|
rv += QLatin1String( "removed flags (" );
|
||||||
|
rv += QString::fromLatin1( ImapParser::join( d->removedFlags.toList(), ", " ) );
|
||||||
|
rv += QLatin1String( ") " );
|
||||||
|
break;
|
||||||
|
case ModifyTags: {
|
||||||
|
rv += QLatin1String( "added tags (" );
|
||||||
|
QList<QByteArray> tags;
|
||||||
|
Q_FOREACH ( qint64 tagId, d->addedTags ) {
|
||||||
|
tags << QByteArray::number( tagId );
|
||||||
|
}
|
||||||
|
rv += QString::fromLatin1( ImapParser::join( tags, ", " ) );
|
||||||
|
rv += QLatin1String( ") " );
|
||||||
|
|
||||||
|
tags.clear();
|
||||||
|
Q_FOREACH ( qint64 tagId, d->removedTags ) {
|
||||||
|
tags << QByteArray::number( tagId );
|
||||||
|
}
|
||||||
|
rv += QLatin1String( "removed tags (" );
|
||||||
|
rv += QString::fromLatin1( ImapParser::join( tags, ", " ) );
|
||||||
|
rv += QLatin1String( ") " );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Move:
|
||||||
|
rv += QLatin1String( "moved" );
|
||||||
|
break;
|
||||||
|
case Remove:
|
||||||
|
rv += QLatin1String( "removed" );
|
||||||
|
break;
|
||||||
|
case Link:
|
||||||
|
rv += QLatin1String( "linked" );
|
||||||
|
break;
|
||||||
|
case Unlink:
|
||||||
|
rv += QLatin1String( "unlinked" );
|
||||||
|
break;
|
||||||
|
case Subscribe:
|
||||||
|
rv += QLatin1String( "subscribed" );
|
||||||
|
break;
|
||||||
|
case Unsubscribe:
|
||||||
|
rv += QLatin1String( "unsubscribed" );
|
||||||
|
break;
|
||||||
|
case InvalidOp:
|
||||||
|
return QLatin1String( "*INVALID OPERATION*" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( d->parentDestCollection >= 0 ) {
|
||||||
|
rv += QString::fromLatin1( " to collection %1" ).arg( d->parentDestCollection );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &arg, const Akonadi::NotificationMessageV2 &msg )
|
||||||
|
{
|
||||||
|
arg.beginStructure();
|
||||||
|
arg << msg.sessionId();
|
||||||
|
arg << static_cast<int>( msg.type() );
|
||||||
|
arg << static_cast<int>( msg.operation() );
|
||||||
|
arg << msg.entities().values();
|
||||||
|
arg << msg.resource();
|
||||||
|
arg << msg.destinationResource();
|
||||||
|
arg << msg.parentCollection();
|
||||||
|
arg << msg.parentDestCollection();
|
||||||
|
|
||||||
|
QStringList itemParts;
|
||||||
|
Q_FOREACH ( const QByteArray &itemPart, msg.itemParts() ) {
|
||||||
|
itemParts.append( QString::fromLatin1( itemPart ) );
|
||||||
|
}
|
||||||
|
arg << itemParts;
|
||||||
|
|
||||||
|
arg << msg.addedFlags().toList();
|
||||||
|
arg << msg.removedFlags().toList();
|
||||||
|
|
||||||
|
arg.endStructure();
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, Akonadi::NotificationMessageV2 &msg )
|
||||||
|
{
|
||||||
|
QByteArray ba;
|
||||||
|
int i;
|
||||||
|
QList<NotificationMessageV2::Entity> items;
|
||||||
|
NotificationMessageV2::Id id;
|
||||||
|
QString str;
|
||||||
|
QStringList strl;
|
||||||
|
QList<QByteArray> bal;
|
||||||
|
|
||||||
|
arg.beginStructure();
|
||||||
|
arg >> ba;
|
||||||
|
msg.setSessionId( ba );
|
||||||
|
arg >> i;
|
||||||
|
msg.setType( static_cast<NotificationMessageV2::Type>( i ) );
|
||||||
|
arg >> i;
|
||||||
|
msg.setOperation( static_cast<NotificationMessageV2::Operation>( i ) );
|
||||||
|
arg >> items;
|
||||||
|
msg.setEntities( items );
|
||||||
|
arg >> ba;
|
||||||
|
msg.setResource( ba );
|
||||||
|
arg >> ba;
|
||||||
|
msg.setDestinationResource( ba );
|
||||||
|
arg >> id;
|
||||||
|
msg.setParentCollection( id );
|
||||||
|
arg >> id;
|
||||||
|
msg.setParentDestCollection( id );
|
||||||
|
|
||||||
|
arg >> strl;
|
||||||
|
|
||||||
|
QSet<QByteArray> itemParts;
|
||||||
|
Q_FOREACH ( const QString &itemPart, strl ) {
|
||||||
|
itemParts.insert( itemPart.toLatin1() );
|
||||||
|
}
|
||||||
|
msg.setItemParts( itemParts );
|
||||||
|
|
||||||
|
arg >> bal;
|
||||||
|
msg.setAddedFlags( bal.toSet() );
|
||||||
|
arg >> bal;
|
||||||
|
msg.setRemovedFlags( bal.toSet() );
|
||||||
|
|
||||||
|
arg.endStructure();
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &arg, const Akonadi::NotificationMessageV2::Entity &item )
|
||||||
|
{
|
||||||
|
arg.beginStructure();
|
||||||
|
arg << item.id;
|
||||||
|
arg << item.remoteId;
|
||||||
|
arg << item.remoteRevision;
|
||||||
|
arg << item.mimeType;
|
||||||
|
arg.endStructure();
|
||||||
|
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, Akonadi::NotificationMessageV2::Entity &item )
|
||||||
|
{
|
||||||
|
arg.beginStructure();
|
||||||
|
arg >> item.id;
|
||||||
|
arg >> item.remoteId;
|
||||||
|
arg >> item.remoteRevision;
|
||||||
|
arg >> item.mimeType;
|
||||||
|
arg.endStructure();
|
||||||
|
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &arg, Akonadi::NotificationMessageV2::Type type )
|
||||||
|
{
|
||||||
|
arg.beginStructure();
|
||||||
|
arg << static_cast<int>( type );
|
||||||
|
arg.endStructure();
|
||||||
|
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, Akonadi::NotificationMessageV2::Type &type )
|
||||||
|
{
|
||||||
|
int t;
|
||||||
|
arg.beginStructure();
|
||||||
|
arg >> t;
|
||||||
|
arg.endStructure();
|
||||||
|
type = static_cast<NotificationMessageV2::Type>( t );
|
||||||
|
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint qHash( const Akonadi::NotificationMessageV2 &msg )
|
||||||
|
{
|
||||||
|
uint i = 0;
|
||||||
|
Q_FOREACH ( const NotificationMessageV2::Entity &item, msg.entities() ) {
|
||||||
|
i += item.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return qHash( i + ( msg.type() << 31 ) + ( msg.operation() << 28 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<NotificationMessage> NotificationMessageV2::toNotificationV1() const
|
||||||
|
{
|
||||||
|
QVector<NotificationMessage> v1;
|
||||||
|
|
||||||
|
Q_FOREACH ( const Entity &item, d->items ) {
|
||||||
|
NotificationMessage msgv1;
|
||||||
|
msgv1.setSessionId( d->sessionId );
|
||||||
|
msgv1.setUid( item.id );
|
||||||
|
msgv1.setRemoteId( item.remoteId );
|
||||||
|
msgv1.setMimeType( item.mimeType );
|
||||||
|
msgv1.setType( static_cast<NotificationMessage::Type>( d->type ) );
|
||||||
|
if ( d->operation == ModifyFlags ) {
|
||||||
|
msgv1.setOperation( NotificationMessage::Modify );
|
||||||
|
} else {
|
||||||
|
msgv1.setOperation( static_cast<NotificationMessage::Operation>( d->operation ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
msgv1.setResource( d->resource );
|
||||||
|
msgv1.setDestinationResource( d->destResource );
|
||||||
|
msgv1.setParentCollection( d->parentCollection );
|
||||||
|
msgv1.setParentDestCollection( d->parentDestCollection );
|
||||||
|
|
||||||
|
// Backward compatibility hack
|
||||||
|
QSet<QByteArray> parts;
|
||||||
|
if ( d->operation == Remove ) {
|
||||||
|
QByteArray rr = item.remoteRevision.toLatin1();
|
||||||
|
parts << ( rr.isEmpty() ? "1" : rr );
|
||||||
|
} else if ( d->operation == ModifyFlags ) {
|
||||||
|
parts << "FLAGS";
|
||||||
|
} else {
|
||||||
|
parts = d->parts;
|
||||||
|
}
|
||||||
|
msgv1.setItemParts( parts );
|
||||||
|
|
||||||
|
v1 << msgv1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotificationMessageV2::appendAndCompress( NotificationMessageV2::List &list, const NotificationMessageV2 &msg )
|
||||||
|
{
|
||||||
|
return NotificationMessageHelpers::appendAndCompressImpl<NotificationMessageV2::List, NotificationMessageV2>( list, msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotificationMessageV2::appendAndCompress( QList<NotificationMessageV2> &list, const NotificationMessageV2 &msg )
|
||||||
|
{
|
||||||
|
return NotificationMessageHelpers::appendAndCompressImpl<QList<NotificationMessageV2>, NotificationMessageV2>( list, msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<( QDebug dbg, const NotificationMessageV2::Entity &entity)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "(ID: " << entity.id;
|
||||||
|
if (!entity.remoteId.isEmpty()) {
|
||||||
|
dbg.nospace() << " RID: " << entity.remoteId;
|
||||||
|
}
|
||||||
|
if (!entity.remoteRevision.isEmpty()) {
|
||||||
|
dbg.nospace() << " RREV: " << entity.remoteRevision;
|
||||||
|
}
|
||||||
|
if (!entity.mimeType.isEmpty()) {
|
||||||
|
dbg.nospace() << " MimeType: " << entity.mimeType;
|
||||||
|
}
|
||||||
|
dbg.nospace() << ")";
|
||||||
|
return dbg;
|
||||||
|
}
|
190
akonadi/libs/notificationmessagev2_p.h
Normal file
190
akonadi/libs/notificationmessagev2_p.h
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
Copyright (c) 2013 Daniel Vrátil <dvratil@redhat.com>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_NOTIFICATIONMESSAGEV2_H
|
||||||
|
#define AKONADI_NOTIFICATIONMESSAGEV2_H
|
||||||
|
|
||||||
|
#include "akonadiprotocolinternals_export.h"
|
||||||
|
|
||||||
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QVector>
|
||||||
|
#include <QtCore/QSet>
|
||||||
|
#include <QtCore/QQueue>
|
||||||
|
#include <QtCore/QMetaType>
|
||||||
|
#include <QtCore/QSharedDataPointer>
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
#include <QtDBus/QDBusArgument>
|
||||||
|
#include "notificationmessage_p.h"
|
||||||
|
|
||||||
|
namespace Akonadi
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
@internal
|
||||||
|
Used for sending notification signals over DBus.
|
||||||
|
DBus type: (ayiia(xsss)ayayxxasaayaay)
|
||||||
|
*/
|
||||||
|
class AKONADIPROTOCOLINTERNALS_EXPORT NotificationMessageV2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef QVector<NotificationMessageV2> List;
|
||||||
|
typedef qint64 Id;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
InvalidType,
|
||||||
|
Collections,
|
||||||
|
Items,
|
||||||
|
Tags
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOTE: Keep this BC with NotificationMessage - i.e. append new stuff to the end
|
||||||
|
enum Operation {
|
||||||
|
InvalidOp,
|
||||||
|
Add,
|
||||||
|
Modify,
|
||||||
|
Move,
|
||||||
|
Remove,
|
||||||
|
Link,
|
||||||
|
Unlink,
|
||||||
|
Subscribe,
|
||||||
|
Unsubscribe,
|
||||||
|
ModifyFlags,
|
||||||
|
ModifyTags
|
||||||
|
};
|
||||||
|
|
||||||
|
class Entity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Entity()
|
||||||
|
: id( -1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==( const Entity &other ) const {
|
||||||
|
return id == other.id
|
||||||
|
&& remoteId == other.remoteId
|
||||||
|
&& remoteRevision == other.remoteRevision
|
||||||
|
&& mimeType == other.mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
Id id;
|
||||||
|
QString remoteId;
|
||||||
|
QString remoteRevision;
|
||||||
|
QString mimeType;
|
||||||
|
};
|
||||||
|
|
||||||
|
NotificationMessageV2();
|
||||||
|
NotificationMessageV2( const NotificationMessageV2 &other );
|
||||||
|
~NotificationMessageV2();
|
||||||
|
|
||||||
|
NotificationMessageV2 &operator=( const NotificationMessageV2 &other );
|
||||||
|
bool operator==( const NotificationMessageV2 &other ) const;
|
||||||
|
bool operator!=( const NotificationMessageV2 &other ) const
|
||||||
|
{
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void registerDBusTypes();
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
|
NotificationMessageV2::Type type() const;
|
||||||
|
void setType( NotificationMessageV2::Type type );
|
||||||
|
|
||||||
|
NotificationMessageV2::Operation operation() const;
|
||||||
|
void setOperation( NotificationMessageV2::Operation operation );
|
||||||
|
|
||||||
|
QByteArray sessionId() const;
|
||||||
|
void setSessionId( const QByteArray &session );
|
||||||
|
|
||||||
|
void addEntity( Id id, const QString &remoteId = QString(), const QString &remoteRevision = QString(), const QString &mimeType = QString() );
|
||||||
|
void setEntities( const QList<NotificationMessageV2::Entity> &items );
|
||||||
|
QMap<Id, NotificationMessageV2::Entity> entities() const;
|
||||||
|
NotificationMessageV2::Entity entity( Id id ) const;
|
||||||
|
QList<Id> uids() const;
|
||||||
|
void clearEntities();
|
||||||
|
|
||||||
|
QByteArray resource() const;
|
||||||
|
void setResource( const QByteArray &resource );
|
||||||
|
|
||||||
|
Id parentCollection() const;
|
||||||
|
void setParentCollection( Id parent );
|
||||||
|
|
||||||
|
Id parentDestCollection() const;
|
||||||
|
void setParentDestCollection( Id parent );
|
||||||
|
|
||||||
|
QByteArray destinationResource() const;
|
||||||
|
void setDestinationResource( const QByteArray &destResource );
|
||||||
|
|
||||||
|
QSet<QByteArray> itemParts() const;
|
||||||
|
void setItemParts( const QSet<QByteArray> &parts );
|
||||||
|
|
||||||
|
QSet<QByteArray> addedFlags() const;
|
||||||
|
void setAddedFlags( const QSet<QByteArray> &parts );
|
||||||
|
|
||||||
|
QSet<QByteArray> removedFlags() const;
|
||||||
|
void setRemovedFlags( const QSet<QByteArray> &parts );
|
||||||
|
|
||||||
|
QSet<qint64> addedTags() const;
|
||||||
|
void setAddedTags( const QSet<qint64> &tags );
|
||||||
|
|
||||||
|
QSet<qint64> removedTags() const;
|
||||||
|
void setRemovedTags( const QSet<qint64> &tags );
|
||||||
|
|
||||||
|
QString toString() const;
|
||||||
|
|
||||||
|
QVector<NotificationMessage> toNotificationV1() const;
|
||||||
|
|
||||||
|
static bool appendAndCompress( NotificationMessageV2::List &list, const NotificationMessageV2 &msg );
|
||||||
|
static bool appendAndCompress( QList<NotificationMessageV2> &list, const NotificationMessageV2 &msg );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
class Private;
|
||||||
|
QSharedDataPointer<Private> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Akonadi
|
||||||
|
|
||||||
|
AKONADIPROTOCOLINTERNALS_EXPORT QDebug operator<<( QDebug debug, const Akonadi::NotificationMessageV2::Entity &entity );
|
||||||
|
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, Akonadi::NotificationMessageV2 &msg );
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &arg, const Akonadi::NotificationMessageV2 &msg );
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, Akonadi::NotificationMessageV2::Entity &item );
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &arg, const Akonadi::NotificationMessageV2::Entity &item );
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, Akonadi::NotificationMessageV2::Type &type );
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &qrg, Akonadi::NotificationMessageV2::Type type );
|
||||||
|
uint qHash( const Akonadi::NotificationMessageV2 &msg );
|
||||||
|
|
||||||
|
Q_DECLARE_TYPEINFO( Akonadi::NotificationMessageV2, Q_MOVABLE_TYPE );
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::NotificationMessageV2 )
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::NotificationMessageV2::Entity )
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::NotificationMessageV2::List )
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::NotificationMessageV2::Type )
|
||||||
|
Q_DECLARE_METATYPE( QVector<Akonadi::NotificationMessageV2::Type> )
|
||||||
|
Q_DECLARE_METATYPE( QVector<QByteArray> )
|
||||||
|
Q_DECLARE_METATYPE( QVector<qint64> )
|
||||||
|
|
||||||
|
// V3 is used in NotificationSource.xml interface, so it must be
|
||||||
|
// defined so that old clients that only include this header
|
||||||
|
// will compile
|
||||||
|
#include "notificationmessagev3_p.h"
|
||||||
|
|
||||||
|
#endif // NOTIFICATIONMESSAGEV2_H
|
115
akonadi/libs/notificationmessagev2_p_p.h
Normal file
115
akonadi/libs/notificationmessagev2_p_p.h
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_NOTIFICATIONMESSAGEV2_P_H
|
||||||
|
#define AKONADI_NOTIFICATIONMESSAGEV2_P_H
|
||||||
|
|
||||||
|
#include "notificationmessagev2_p.h"
|
||||||
|
|
||||||
|
namespace Akonadi
|
||||||
|
{
|
||||||
|
|
||||||
|
class NotificationMessageHelpers
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
static bool compareWithoutOpAndParts( const T &left, const T &right )
|
||||||
|
{
|
||||||
|
return left.entities() == right.entities()
|
||||||
|
&& left.type() == right.type()
|
||||||
|
&& left.sessionId() == right.sessionId()
|
||||||
|
&& left.resource() == right.resource()
|
||||||
|
&& left.destinationResource() == right.destinationResource()
|
||||||
|
&& left.parentCollection() == right.parentCollection()
|
||||||
|
&& left.parentDestCollection() == right.parentDestCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename List, typename Msg>
|
||||||
|
static bool appendAndCompressImpl( List &list, const Msg &msg )
|
||||||
|
{
|
||||||
|
// fast-path for stuff that is not considered during O(n) compression below
|
||||||
|
if ( msg.operation() != NotificationMessageV2::Add && msg.operation() != NotificationMessageV2::Link
|
||||||
|
&& msg.operation() != NotificationMessageV2::Unlink && msg.operation() != NotificationMessageV2::Subscribe
|
||||||
|
&& msg.operation() != NotificationMessageV2::Unsubscribe && msg.operation() != NotificationMessageV2::Move ) {
|
||||||
|
|
||||||
|
typename List::Iterator end = list.end();
|
||||||
|
for ( typename List::Iterator it = list.begin(); it != end; ) {
|
||||||
|
if ( compareWithoutOpAndParts( msg, ( *it ) ) ) {
|
||||||
|
|
||||||
|
// both are modifications, merge them together and drop the new one
|
||||||
|
if ( msg.operation() == NotificationMessageV2::Modify && it->operation() == NotificationMessageV2::Modify ) {
|
||||||
|
( *it ).setItemParts( ( *it ).itemParts() + msg.itemParts() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( msg.operation() == NotificationMessageV2::ModifyFlags && it->operation() == NotificationMessageV2::ModifyFlags ) {
|
||||||
|
( *it ).setAddedFlags( ( *it ).addedFlags() + msg.addedFlags() );
|
||||||
|
( *it ).setRemovedFlags( ( *it ).removedFlags() + msg.removedFlags() );
|
||||||
|
|
||||||
|
// If merged notifications result in no-change notification, drop both.
|
||||||
|
if ( ( *it ).addedFlags() == ( *it ).removedFlags() ) {
|
||||||
|
it = list.erase( it );
|
||||||
|
end = list.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( msg.operation() == NotificationMessageV2::ModifyTags && it->operation() == NotificationMessageV2::ModifyTags ) {
|
||||||
|
( *it ).setAddedTags( ( *it ).addedTags() + msg.addedTags() );
|
||||||
|
( *it ).setRemovedTags( ( *it ).removedTags() + msg.removedTags() );
|
||||||
|
|
||||||
|
// If merged notification results in no-change notification, drop both
|
||||||
|
if ( ( *it ).addedTags() == ( *it ).removedTags() ) {
|
||||||
|
it = list.erase( it );
|
||||||
|
end = list.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// new one is a modification, the existing one not, so drop the new one
|
||||||
|
else if ( ( ( msg.operation() == NotificationMessageV2::Modify ) || ( msg.operation() == NotificationMessageV2::ModifyFlags ) )
|
||||||
|
&& ( ( *it ).operation() != NotificationMessageV2::Modify )
|
||||||
|
&& ( *it ).operation() != NotificationMessageV2::ModifyFlags
|
||||||
|
&& ( *it ).operation() != NotificationMessageV2::ModifyTags ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// new one is a deletion, erase the existing modification ones (and keep going, in case there are more)
|
||||||
|
else if ( msg.operation() == NotificationMessageV2::Remove && ( ( *it ).operation() == NotificationMessageV2::Modify || ( *it ).operation() == NotificationMessageV2::ModifyFlags || ( *it ).operation() == NotificationMessageV2::ModifyTags ) ) {
|
||||||
|
it = list.erase( it );
|
||||||
|
end = list.end();
|
||||||
|
}
|
||||||
|
// keep looking
|
||||||
|
else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list.append( msg );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
215
akonadi/libs/notificationmessagev3.cpp
Normal file
215
akonadi/libs/notificationmessagev3.cpp
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014 Daniel Vrátil <dvratil@redhat.com>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "notificationmessagev3_p.h"
|
||||||
|
#include "notificationmessagev2_p_p.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDBusMetaType>
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
NotificationMessageV3::NotificationMessageV3()
|
||||||
|
: NotificationMessageV2()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV3::NotificationMessageV3( const NotificationMessageV3 &other )
|
||||||
|
: NotificationMessageV2( other )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV3::~NotificationMessageV3()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV3::registerDBusTypes()
|
||||||
|
{
|
||||||
|
qDBusRegisterMetaType<Akonadi::NotificationMessageV3>();
|
||||||
|
qDBusRegisterMetaType<Akonadi::NotificationMessageV3::List>();
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationMessageV2::List NotificationMessageV3::toV2List( const NotificationMessageV3::List &list )
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List out;
|
||||||
|
out.reserve( list.size() );
|
||||||
|
Q_FOREACH ( const NotificationMessageV3 &v3, list ) {
|
||||||
|
out << static_cast<NotificationMessageV2>( v3 );
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotificationMessageV3::appendAndCompress( NotificationMessageV3::List &list, const NotificationMessageV3 &msg )
|
||||||
|
{
|
||||||
|
return NotificationMessageHelpers::appendAndCompressImpl<NotificationMessageV3::List, NotificationMessageV3>( list, msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NotificationMessageV3::appendAndCompress( QList<NotificationMessageV3> &list, const NotificationMessageV3 &msg )
|
||||||
|
{
|
||||||
|
return NotificationMessageHelpers::appendAndCompressImpl<QList<NotificationMessageV3>, NotificationMessageV3>( list, msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, NotificationMessageV3 &msg )
|
||||||
|
{
|
||||||
|
QByteArray ba;
|
||||||
|
int i;
|
||||||
|
QList<NotificationMessageV2::Entity> items;
|
||||||
|
NotificationMessageV2::Id id;
|
||||||
|
QString str;
|
||||||
|
QStringList strl;
|
||||||
|
QList<QByteArray> bal;
|
||||||
|
QList<qint64> intl;
|
||||||
|
|
||||||
|
arg.beginStructure();
|
||||||
|
arg >> ba;
|
||||||
|
msg.setSessionId( ba );
|
||||||
|
arg >> i;
|
||||||
|
msg.setType( static_cast<NotificationMessageV2::Type>( i ) );
|
||||||
|
arg >> i;
|
||||||
|
msg.setOperation( static_cast<NotificationMessageV2::Operation>( i ) );
|
||||||
|
arg >> items;
|
||||||
|
msg.setEntities( items );
|
||||||
|
arg >> ba;
|
||||||
|
msg.setResource( ba );
|
||||||
|
arg >> ba;
|
||||||
|
msg.setDestinationResource( ba );
|
||||||
|
arg >> id;
|
||||||
|
msg.setParentCollection( id );
|
||||||
|
arg >> id;
|
||||||
|
msg.setParentDestCollection( id );
|
||||||
|
|
||||||
|
arg >> strl;
|
||||||
|
|
||||||
|
QSet<QByteArray> itemParts;
|
||||||
|
Q_FOREACH ( const QString &itemPart, strl ) {
|
||||||
|
itemParts.insert( itemPart.toLatin1() );
|
||||||
|
}
|
||||||
|
msg.setItemParts( itemParts );
|
||||||
|
|
||||||
|
arg >> bal;
|
||||||
|
msg.setAddedFlags( bal.toSet() );
|
||||||
|
arg >> bal;
|
||||||
|
msg.setRemovedFlags( bal.toSet() );
|
||||||
|
arg >> intl;
|
||||||
|
msg.setAddedTags( intl.toSet() );
|
||||||
|
arg >> intl;
|
||||||
|
msg.setRemovedTags( intl.toSet() );
|
||||||
|
|
||||||
|
arg.endStructure();
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &arg, const NotificationMessageV3 &msg )
|
||||||
|
{
|
||||||
|
arg.beginStructure();
|
||||||
|
arg << msg.sessionId();
|
||||||
|
arg << static_cast<int>( msg.type() );
|
||||||
|
arg << static_cast<int>( msg.operation() );
|
||||||
|
arg << msg.entities().values();
|
||||||
|
arg << msg.resource();
|
||||||
|
arg << msg.destinationResource();
|
||||||
|
arg << msg.parentCollection();
|
||||||
|
arg << msg.parentDestCollection();
|
||||||
|
|
||||||
|
QStringList itemParts;
|
||||||
|
Q_FOREACH ( const QByteArray &itemPart, msg.itemParts() ) {
|
||||||
|
itemParts.append( QString::fromLatin1( itemPart ) );
|
||||||
|
}
|
||||||
|
arg << itemParts;
|
||||||
|
|
||||||
|
arg << msg.addedFlags().toList();
|
||||||
|
arg << msg.removedFlags().toList();
|
||||||
|
arg << msg.addedTags().toList();
|
||||||
|
arg << msg.removedTags().toList();
|
||||||
|
|
||||||
|
arg.endStructure();
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<( QDebug dbg, const NotificationMessageV3 &msg )
|
||||||
|
{
|
||||||
|
dbg.nospace() << "NotificationMessageV3 {\n";
|
||||||
|
dbg.nospace() << "\tType: ";
|
||||||
|
switch (msg.type()) {
|
||||||
|
case NotificationMessageV2::InvalidType:
|
||||||
|
dbg.nospace() << QLatin1String("Invalid");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Items:
|
||||||
|
dbg.nospace() << QLatin1String("Items");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Collections:
|
||||||
|
dbg.nospace() << QLatin1String("Collections");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Tags:
|
||||||
|
dbg.nospace() << QLatin1String("Tags");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dbg.nospace() << '\n';
|
||||||
|
|
||||||
|
dbg.nospace() << "\tOperation: ";
|
||||||
|
switch( msg.operation()) {
|
||||||
|
case NotificationMessageV2::InvalidOp:
|
||||||
|
dbg.nospace() << QLatin1String("Invalid");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Add:
|
||||||
|
dbg.nospace() << QLatin1String("Add");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Modify:
|
||||||
|
dbg.nospace() << QLatin1String("Modify");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Move:
|
||||||
|
dbg.nospace() << QLatin1String("Move");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Remove:
|
||||||
|
dbg.nospace() << QLatin1String("Remove");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Link:
|
||||||
|
dbg.nospace() << QLatin1String("Link");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Unlink:
|
||||||
|
dbg.nospace() << QLatin1String("Unlink");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Subscribe:
|
||||||
|
dbg.nospace() << QLatin1String("Subscribe");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::Unsubscribe:
|
||||||
|
dbg.nospace() << QLatin1String("Unsubscribe");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::ModifyFlags:
|
||||||
|
dbg.nospace() << QLatin1String("ModifyFlags");
|
||||||
|
break;
|
||||||
|
case NotificationMessageV2::ModifyTags:
|
||||||
|
dbg.nospace() << QLatin1String("ModifyTags");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dbg.nospace() << "\n";
|
||||||
|
dbg.nospace() << "\tSession: " << msg.sessionId() << "\n";
|
||||||
|
dbg.nospace() << "\tEntities: " << msg.entities().values() << "\n";
|
||||||
|
dbg.nospace() << "\tResource: " << msg.resource() << "\n";
|
||||||
|
dbg.nospace() << "\tCollection: " << msg.parentCollection() << "\n";
|
||||||
|
dbg.nospace() << "\tDestination resource: " << msg.destinationResource() << "\n";
|
||||||
|
dbg.nospace() << "\tDestination collection: " << msg.parentDestCollection() << "\n";
|
||||||
|
dbg.nospace() << "\tParts: " << msg.itemParts() << "\n";
|
||||||
|
dbg.nospace() << "\tAdded flags: " << msg.addedFlags() << "\n";
|
||||||
|
dbg.nospace() << "\tRemoved flags: " << msg.removedFlags() << "\n";
|
||||||
|
dbg.nospace() << "\tAdded tags: " << msg.addedTags() << "\n";
|
||||||
|
dbg.nospace() << "\tRemoved tags: " << msg.removedTags() << "\n";
|
||||||
|
dbg.nospace() << "}" << "\n";
|
||||||
|
return dbg;
|
||||||
|
}
|
60
akonadi/libs/notificationmessagev3_p.h
Normal file
60
akonadi/libs/notificationmessagev3_p.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014 Daniel Vrátil <dvratil@redhat.com>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_NOTIFICATIONMESSAGEV3_H
|
||||||
|
#define AKONADI_NOTIFICATIONMESSAGEV3_H
|
||||||
|
|
||||||
|
#include "akonadiprotocolinternals_export.h"
|
||||||
|
|
||||||
|
#include "notificationmessagev2_p.h"
|
||||||
|
#include <QDBusArgument>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace Akonadi
|
||||||
|
{
|
||||||
|
|
||||||
|
class AKONADIPROTOCOLINTERNALS_EXPORT NotificationMessageV3 : public Akonadi::NotificationMessageV2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef QVector<NotificationMessageV3> List;
|
||||||
|
|
||||||
|
static void registerDBusTypes();
|
||||||
|
|
||||||
|
NotificationMessageV3();
|
||||||
|
NotificationMessageV3( const NotificationMessageV3 &other );
|
||||||
|
~NotificationMessageV3();
|
||||||
|
|
||||||
|
static NotificationMessageV2::List toV2List( const NotificationMessageV3::List &list );
|
||||||
|
static bool appendAndCompress( NotificationMessageV3::List &list, const NotificationMessageV3 &msg );
|
||||||
|
static bool appendAndCompress( QList<NotificationMessageV3> &list, const NotificationMessageV3 &msg );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AKONADIPROTOCOLINTERNALS_EXPORT QDebug operator<<(QDebug dbg, const Akonadi::NotificationMessageV3 &msg);
|
||||||
|
|
||||||
|
const QDBusArgument &operator>>( const QDBusArgument &arg, Akonadi::NotificationMessageV3 &msg );
|
||||||
|
QDBusArgument &operator<<( QDBusArgument &arg, const Akonadi::NotificationMessageV3 &msg );
|
||||||
|
|
||||||
|
Q_DECLARE_TYPEINFO( Akonadi::NotificationMessageV3, Q_MOVABLE_TYPE );
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::NotificationMessageV3 )
|
||||||
|
Q_DECLARE_METATYPE( Akonadi::NotificationMessageV3::List )
|
||||||
|
|
||||||
|
#endif // AKONADI_NOTIFICATIONMESSAGEV3_H
|
170
akonadi/libs/protocol_p.h
Normal file
170
akonadi/libs/protocol_p.h
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_PROTOCOL_P_H
|
||||||
|
#define AKONADI_PROTOCOL_P_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file protocol_p.h Shared constants used in the communication protocol between
|
||||||
|
the Akonadi server and its clients.
|
||||||
|
|
||||||
|
@todo Fill this file with command names, item/collection property names
|
||||||
|
item part names, etc. and replace the usages accordingly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// D-Bus service names
|
||||||
|
#define AKONADI_DBUS_SERVER_SERVICE "org.freedesktop.Akonadi"
|
||||||
|
#define AKONADI_DBUS_CONTROL_SERVICE "org.freedesktop.Akonadi.Control"
|
||||||
|
#define AKONADI_DBUS_CONTROL_SERVICE_LOCK "org.freedesktop.Akonadi.Control.lock"
|
||||||
|
#define AKONADI_DBUS_AGENTSERVER_SERVICE "org.freedesktop.Akonadi.AgentServer"
|
||||||
|
#define AKONADI_DBUS_STORAGEJANITOR_SERVICE "org.freedesktop.Akonadi.Janitor"
|
||||||
|
#define AKONADI_DBUS_SERVER_SERVICE_UPGRADING "org.freedesktop.Akonadi.upgrading"
|
||||||
|
|
||||||
|
#define AKONADI_DBUS_AGENTMANAGER_PATH "/AgentManager"
|
||||||
|
#define AKONADI_DBUS_AGENTSERVER_PATH "/AgentServer"
|
||||||
|
#define AKONADI_DBUS_STORAGEJANITOR_PATH "/Janitor"
|
||||||
|
|
||||||
|
// Commands
|
||||||
|
#define AKONADI_CMD_APPEND "APPEND"
|
||||||
|
#define AKONADI_CMD_BEGIN "BEGIN"
|
||||||
|
#define AKONADI_CMD_CAPABILITY "CAPABILITY"
|
||||||
|
#define AKONADI_CMD_COLLECTION "COLLECTION"
|
||||||
|
#define AKONADI_CMD_COLLECTIONCOPY "COLCOPY"
|
||||||
|
#define AKONADI_CMD_COLLECTIONMOVE "COLMOVE"
|
||||||
|
#define AKONADI_CMD_COMMIT "COMMIT"
|
||||||
|
#define AKONADI_CMD_ITEMCOPY "COPY"
|
||||||
|
#define AKONADI_CMD_COLLECTIONCREATE "CREATE"
|
||||||
|
#define AKONADI_CMD_COLLECTIONDELETE "DELETE"
|
||||||
|
#define AKONADI_CMD_EXPUNGE "EXPUNGE"
|
||||||
|
#define AKONADI_CMD_ITEMFETCH "FETCH"
|
||||||
|
#define AKONADI_CMD_GID "GID"
|
||||||
|
#define AKONADI_CMD_HRID "HRID"
|
||||||
|
#define AKONADI_CMD_ITEMLINK "LINK"
|
||||||
|
#define AKONADI_CMD_LIST "LIST"
|
||||||
|
#define AKONADI_CMD_LOGIN "LOGIN"
|
||||||
|
#define AKONADI_CMD_LOGOUT "LOGOUT"
|
||||||
|
#define AKONADI_CMD_LSUB "LSUB"
|
||||||
|
#define AKONADI_CMD_MERGE "MERGE"
|
||||||
|
#define AKONADI_CMD_COLLECTIONMODIFY "MODIFY"
|
||||||
|
#define AKONADI_CMD_ITEMMOVE "MOVE"
|
||||||
|
#define AKONADI_CMD_ITEMDELETE "REMOVE"
|
||||||
|
#define AKONADI_CMD_RESOURCESELECT "RESSELECT"
|
||||||
|
#define AKONADI_CMD_RID "RID"
|
||||||
|
#define AKONADI_CMD_ROLLBACK "ROLLBACK"
|
||||||
|
#define AKONADI_CMD_SUBSCRIBE "SUBSCRIBE"
|
||||||
|
#define AKONADI_CMD_SEARCH "SEARCH"
|
||||||
|
#define AKONADI_CMD_SEARCH_RESULT "SEARCH_RESULT"
|
||||||
|
#define AKONADI_CMD_SEARCH_STORE "SEARCH_STORE"
|
||||||
|
#define AKONADI_CMD_SELECT "SELECT"
|
||||||
|
#define AKONADI_CMD_STATUS "STATUS"
|
||||||
|
#define AKONADI_CMD_ITEMMODIFY "STORE"
|
||||||
|
#define AKONADI_CMD_TAGAPPEND "TAGAPPEND"
|
||||||
|
#define AKONADI_CMD_TAGFETCH "TAGFETCH"
|
||||||
|
#define AKONADI_CMD_TAGREMOVE "TAGREMOVE"
|
||||||
|
#define AKONADI_CMD_TAGSTORE "TAGSTORE"
|
||||||
|
#define AKONADI_CMD_UID "UID"
|
||||||
|
#define AKONADI_CMD_ITEMUNLINK "UNLINK"
|
||||||
|
#define AKONADI_CMD_UNSUBSCRIBE "UNSUBSCRIBE"
|
||||||
|
#define AKONADI_CMD_ITEMCREATE "X-AKAPPEND"
|
||||||
|
#define AKONADI_CMD_X_AKLIST "X-AKLIST"
|
||||||
|
#define AKONADI_CMD_X_AKLSUB "X-AKLSUB"
|
||||||
|
|
||||||
|
// Command parameters
|
||||||
|
#define AKONADI_PARAM_CAPABILITY_AKAPPENDSTREAMING "AKAPPENDSTREAMING"
|
||||||
|
#define AKONADI_PARAM_ALLATTRIBUTES "ALLATTR"
|
||||||
|
#define AKONADI_PARAM_ANCESTORS "ANCESTORS"
|
||||||
|
#define AKONADI_PARAM_ATR "ATR:"
|
||||||
|
#define AKONADI_PARAM_CACHEONLY "CACHEONLY"
|
||||||
|
#define AKONADI_PARAM_CACHEDPARTS "CACHEDPARTS"
|
||||||
|
#define AKONADI_PARAM_CACHETIMEOUT "CACHETIMEOUT"
|
||||||
|
#define AKONADI_PARAM_CACHEPOLICY "CACHEPOLICY"
|
||||||
|
#define AKONADI_PARAM_CHANGEDSINCE "CHANGEDSINCE"
|
||||||
|
#define AKONADI_PARAM_CHARSET "CHARSET"
|
||||||
|
#define AKONADI_PARAM_CHECKCACHEDPARTSONLY "CHECKCACHEDPARTSONLY"
|
||||||
|
#define AKONADI_PARAM_COLLECTION "COLLECTION"
|
||||||
|
#define AKONADI_PARAM_COLLECTIONID "COLLECTIONID"
|
||||||
|
#define AKONADI_PARAM_COLLECTIONS "COLLECTIONS"
|
||||||
|
#define AKONADI_PARAM_MTIME "DATETIME"
|
||||||
|
#define AKONADI_PARAM_CAPABILITY_DIRECTSTREAMING "DIRECTSTREAMING"
|
||||||
|
#define AKONADI_PARAM_UNDIRTY "DIRTY"
|
||||||
|
#define AKONADI_PARAM_DISPLAY "DISPLAY"
|
||||||
|
#define AKONADI_PARAM_EXTERNALPAYLOAD "EXTERNALPAYLOAD"
|
||||||
|
#define AKONADI_PARAM_ENABLED "ENABLED"
|
||||||
|
#define AKONADI_PARAM_FLAGS "FLAGS"
|
||||||
|
#define AKONADI_PARAM_TAGS "TAGS"
|
||||||
|
#define AKONADI_PARAM_FULLPAYLOAD "FULLPAYLOAD"
|
||||||
|
#define AKONADI_PARAM_GID "GID"
|
||||||
|
#define AKONADI_PARAM_IGNOREERRORS "IGNOREERRORS"
|
||||||
|
#define AKONADI_PARAM_INDEX "INDEX"
|
||||||
|
#define AKONADI_PARAM_INHERIT "INHERIT"
|
||||||
|
#define AKONADI_PARAM_INTERVAL "INTERVAL"
|
||||||
|
#define AKONADI_PARAM_INVALIDATECACHE "INVALIDATECACHE"
|
||||||
|
#define AKONADI_PARAM_MIMETYPE "MIMETYPE"
|
||||||
|
#define AKONADI_PARAM_MERGE "MERGE"
|
||||||
|
#define AKONADI_PARAM_LOCALPARTS "LOCALPARTS"
|
||||||
|
#define AKONADI_PARAM_NAME "NAME"
|
||||||
|
#define AKONADI_PARAM_CAPABILITY_NOTIFY "NOTIFY"
|
||||||
|
#define AKONADI_PARAM_CAPABILITY_NOPAYLOADPATH "NOPAYLOADPATH"
|
||||||
|
#define AKONADI_PARAM_PARENT "PARENT"
|
||||||
|
#define AKONADI_PARAM_PERSISTENTSEARCH "PERSISTENTSEARCH"
|
||||||
|
#define AKONADI_PARAM_PARTS "PARTS"
|
||||||
|
#define AKONADI_PARAM_PLD "PLD:"
|
||||||
|
#define AKONADI_PARAM_PLD_RFC822 "PLD:RFC822"
|
||||||
|
#define AKONADI_PARAM_PERSISTENTSEARCH_QUERYCOLLECTIONS "QUERYCOLLECTIONS"
|
||||||
|
#define AKONADI_PARAM_PERSISTENTSEARCH_QUERYLANG "QUERYLANGUAGE"
|
||||||
|
#define AKONADI_PARAM_PERSISTENTSEARCH_QUERYSTRING "QUERYSTRING"
|
||||||
|
#define AKONADI_PARAM_QUERY "QUERY"
|
||||||
|
#define AKONADI_PARAM_RECURSIVE "RECURSIVE"
|
||||||
|
#define AKONADI_PARAM_REFERENCED "REFERENCED"
|
||||||
|
#define AKONADI_PARAM_REMOTE "REMOTE"
|
||||||
|
#define AKONADI_PARAM_REMOTEID "REMOTEID"
|
||||||
|
#define AKONADI_PARAM_REMOTEREVISION "REMOTEREVISION"
|
||||||
|
#define AKONADI_PARAM_RESOURCE "RESOURCE"
|
||||||
|
#define AKONADI_PARAM_REVISION "REV"
|
||||||
|
#define AKONADI_PARAM_SILENT "SILENT"
|
||||||
|
#define AKONADI_PARAM_DOT_SILENT ".SILENT"
|
||||||
|
#define AKONADI_PARAM_CAPABILITY_SERVERSEARCH "SERVERSEARCH"
|
||||||
|
#define AKONADI_PARAM_SIZE "SIZE"
|
||||||
|
#define AKONADI_PARAM_STATISTICS "STATISTICS"
|
||||||
|
#define AKONADI_PARAM_SYNC "SYNC"
|
||||||
|
#define AKONADI_PARAM_SYNCONDEMAND "SYNCONDEMAND"
|
||||||
|
#define AKONADI_PARAM_TAG "TAG"
|
||||||
|
#define AKONADI_PARAM_TAGID "TAGID"
|
||||||
|
#define AKONADI_PARAM_UID "UID"
|
||||||
|
#define AKONADI_PARAM_VIRTREF "VIRTREF"
|
||||||
|
#define AKONADI_PARAM_VIRTUAL "VIRTUAL"
|
||||||
|
|
||||||
|
// Flags
|
||||||
|
#define AKONADI_FLAG_GID "\\Gid"
|
||||||
|
#define AKONADI_FLAG_IGNORED "$IGNORED"
|
||||||
|
#define AKONADI_FLAG_MIMETYPE "\\MimeType"
|
||||||
|
#define AKONADI_FLAG_REMOTEID "\\RemoteId"
|
||||||
|
#define AKONADI_FLAG_REMOTEREVISION "\\RemoteRevision"
|
||||||
|
#define AKONADI_FLAG_TAG "\\Tag"
|
||||||
|
#define AKONADI_FLAG_RTAG "\\RTag"
|
||||||
|
#define AKONADI_FLAG_SEEN "\\SEEN"
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
#define AKONADI_ATTRIBUTE_HIDDEN "ATR:HIDDEN"
|
||||||
|
#define AKONADI_ATTRIBUTE_MESSAGES "MESSAGES"
|
||||||
|
#define AKONADI_ATTRIBUTE_UNSEEN "UNSEEN"
|
||||||
|
|
||||||
|
// special resource names
|
||||||
|
#define AKONADI_SEARCH_RESOURCE "akonadi_search_resource"
|
||||||
|
#endif
|
14
akonadi/libs/tests/CMakeLists.txt
Normal file
14
akonadi/libs/tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||||
|
|
||||||
|
macro(add_unit_test _source)
|
||||||
|
set(_test ${_source})
|
||||||
|
get_filename_component(_name ${_source} NAME_WE)
|
||||||
|
add_executable(${_name} ${_source})
|
||||||
|
add_test(akonadi-${_name} ${_name})
|
||||||
|
target_link_libraries(${_name} akonadiprotocolinternals ${QT_QTGUI_LIBRARY} ${QT_QTTEST_LIBRARIES})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
add_unit_test(notificationmessagetest.cpp)
|
||||||
|
add_unit_test(notificationmessagev2test.cpp)
|
||||||
|
add_unit_test(imapparserbenchmark.cpp)
|
101
akonadi/libs/tests/imapparserbenchmark.cpp
Normal file
101
akonadi/libs/tests/imapparserbenchmark.cpp
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QtTest/QTest>
|
||||||
|
#include "../imapparser_p.h"
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE( QList<QByteArray> )
|
||||||
|
|
||||||
|
class ImapParserBenchmark : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private Q_SLOTS:
|
||||||
|
void quote_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QByteArray>( "input" );
|
||||||
|
QTest::newRow( "empty" ) << QByteArray();
|
||||||
|
QTest::newRow( "10-idle" ) << QByteArray( "ababababab" );
|
||||||
|
QTest::newRow( "10-quote" ) << QByteArray( "\"abababab\"" );
|
||||||
|
QTest::newRow( "50-idle" ) << QByteArray( "ababababababababababababababababababababababababab" );
|
||||||
|
QTest::newRow( "50-quote" ) << QByteArray( "\"abababab\ncabababab\ncabababab\ncabababab\ncabababab\"" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void quote()
|
||||||
|
{
|
||||||
|
QFETCH( QByteArray, input );
|
||||||
|
QBENCHMARK {
|
||||||
|
ImapParser::quote( input );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void join_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QList<QByteArray> >( "list" );
|
||||||
|
QTest::newRow( "empty" ) << QList<QByteArray>();
|
||||||
|
QTest::newRow( "single" ) << ( QList<QByteArray>() << "ababab" );
|
||||||
|
QTest::newRow( "two" ) << ( QList<QByteArray>() << "ababab" << "ababab" );
|
||||||
|
QTest::newRow( "five" ) << ( QList<QByteArray>() << "ababab" << "ababab" << "ababab" << "ababab" << "ababab" );
|
||||||
|
QList<QByteArray> list;
|
||||||
|
for ( int i = 0; i < 50; ++i ) {
|
||||||
|
list << "ababab";
|
||||||
|
}
|
||||||
|
QTest::newRow( "a lot" ) << list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void join()
|
||||||
|
{
|
||||||
|
QFETCH( QList<QByteArray>, list );
|
||||||
|
QBENCHMARK {
|
||||||
|
ImapParser::join( list, " " );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseParenthesizedList_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QByteArray>( "data" );
|
||||||
|
QTest::newRow( "empty" ) << QByteArray();
|
||||||
|
QTest::newRow( "unnested" ) << QByteArray("(\"Foo Bar\" NIL \"foobar\" \"test.com\")");
|
||||||
|
QTest::newRow( "nested" ) << QByteArray("((\"Foo Bar\" NIL \"foobar\" \"test.com\"))");
|
||||||
|
QTest::newRow( "nested-long" ) << QByteArray("(UID 86 REV 0 MIMETYPE \"message/rfc822\" COLLECTIONID 13 SIZE 6114 FLAGS (\\SEEN)"
|
||||||
|
" ANCESTORS ((13 \"/INBOX\") (12 \"imap://mail@mail.test.com/\") (0 \"\")) PLD:ENVELOPE[1] {396}"
|
||||||
|
" (\"Fri, 04 Jun 2010 09:07:54 +0200\" \"Re: [ADMIN] foobar available again!\""
|
||||||
|
" ((\"Foo Bar\" NIL \"foobar\" \"test.com\"))"
|
||||||
|
" NIL NIL"
|
||||||
|
" ((\"Asdf Bla Blub\" NIL \"asdf.bla.blub\" \"123test.org\"))"
|
||||||
|
" ((NIL NIL \"muh.kuh\" \"lalala.com\") (\"Konqi KDE\" NIL \"konqi\" \"kde.org\") (NIL NIL \"all\" \"test.com\"))"
|
||||||
|
" NIL \"<201006040905.33367.foo.bar@test.com>\" \"<4C08A64A.9020205@123test.org>\""
|
||||||
|
" \"<201006040142.56540.muh.kuh@lalala.com> <201006040704.39648.konqi@kde.org> <201006040905.33367.foo.bar@test.com>\""
|
||||||
|
"))");
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseParenthesizedList()
|
||||||
|
{
|
||||||
|
QFETCH( QByteArray, data );
|
||||||
|
QVarLengthArray<QByteArray, 16> result;
|
||||||
|
QBENCHMARK {
|
||||||
|
ImapParser::parseParenthesizedList( data, result, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "imapparserbenchmark.moc"
|
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN( ImapParserBenchmark )
|
155
akonadi/libs/tests/notificationmessagetest.cpp
Normal file
155
akonadi/libs/tests/notificationmessagetest.cpp
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "notificationmessagetest.h"
|
||||||
|
#include <notificationmessage_p.h>
|
||||||
|
|
||||||
|
#include <QSet>
|
||||||
|
#include <QtTest/QTest>
|
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN( NotificationMessageTest )
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE( NotificationMessage::Type )
|
||||||
|
|
||||||
|
void NotificationMessageTest::testCompress()
|
||||||
|
{
|
||||||
|
NotificationMessage::List list;
|
||||||
|
NotificationMessage msg;
|
||||||
|
msg.setType( NotificationMessage::Item );
|
||||||
|
msg.setOperation( NotificationMessage::Add );
|
||||||
|
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessage::Modify );
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessage::Add );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessage::Remove );
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 2 ); // should be 2 for collections, 0 for items?
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageTest::testCompress2()
|
||||||
|
{
|
||||||
|
NotificationMessage::List list;
|
||||||
|
NotificationMessage msg;
|
||||||
|
msg.setType( NotificationMessage::Item );
|
||||||
|
msg.setOperation( NotificationMessage::Modify );
|
||||||
|
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessage::Remove );
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessage::Remove );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageTest::testCompress3()
|
||||||
|
{
|
||||||
|
NotificationMessage::List list;
|
||||||
|
NotificationMessage msg;
|
||||||
|
msg.setType( NotificationMessage::Item );
|
||||||
|
msg.setOperation( NotificationMessage::Modify );
|
||||||
|
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageTest::testCompressWithItemParts()
|
||||||
|
{
|
||||||
|
NotificationMessage::List list;
|
||||||
|
NotificationMessage msg;
|
||||||
|
msg.setType( NotificationMessage::Item );
|
||||||
|
msg.setOperation( NotificationMessage::Add );
|
||||||
|
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessage::Modify );
|
||||||
|
QSet<QByteArray> changes;
|
||||||
|
changes.insert( "FLAGS" );
|
||||||
|
msg.setItemParts( changes );
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessage::Add );
|
||||||
|
QCOMPARE( list.first().itemParts(), QSet<QByteArray>() );
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessage::Remove );
|
||||||
|
msg.setItemParts( QSet<QByteArray>() );
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessage::Remove );
|
||||||
|
QCOMPARE( list.first().itemParts(), QSet<QByteArray>() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageTest::testNoCompress()
|
||||||
|
{
|
||||||
|
NotificationMessage::List list;
|
||||||
|
NotificationMessage msg;
|
||||||
|
msg.setType( NotificationMessage::Item );
|
||||||
|
msg.setOperation( NotificationMessage::Modify );
|
||||||
|
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setType( NotificationMessage::Collection );
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageTest::testPartModificationMerge_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<NotificationMessage::Type>( "type" );
|
||||||
|
QTest::newRow( "item" ) << NotificationMessage::Item;
|
||||||
|
QTest::newRow( "collection" ) << NotificationMessage::Collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageTest::testPartModificationMerge()
|
||||||
|
{
|
||||||
|
QFETCH( NotificationMessage::Type, type );
|
||||||
|
|
||||||
|
NotificationMessage::List list;
|
||||||
|
NotificationMessage msg;
|
||||||
|
msg.setType( type );
|
||||||
|
msg.setOperation( NotificationMessage::Modify );
|
||||||
|
msg.setItemParts( QSet<QByteArray>() << "PART1" );
|
||||||
|
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setItemParts( QSet<QByteArray>() << "PART2" );
|
||||||
|
NotificationMessage::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().itemParts(), ( QSet<QByteArray>() << "PART1" << "PART2" ) );
|
||||||
|
}
|
38
akonadi/libs/tests/notificationmessagetest.h
Normal file
38
akonadi/libs/tests/notificationmessagetest.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_NOTIFICATIONMESSAGETEST_H
|
||||||
|
#define AKONADI_NOTIFICATIONMESSAGETEST_H
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
class NotificationMessageTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private Q_SLOTS:
|
||||||
|
void testCompress();
|
||||||
|
void testCompress2();
|
||||||
|
void testCompress3();
|
||||||
|
void testCompressWithItemParts();
|
||||||
|
void testNoCompress();
|
||||||
|
void testPartModificationMerge_data();
|
||||||
|
void testPartModificationMerge();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
248
akonadi/libs/tests/notificationmessagev2test.cpp
Normal file
248
akonadi/libs/tests/notificationmessagev2test.cpp
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
Copyright (c) 2013 Daniel Vrátil <dvratil@redhat.com>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "notificationmessagev2test.h"
|
||||||
|
#include <notificationmessagev2_p.h>
|
||||||
|
|
||||||
|
#include <QSet>
|
||||||
|
#include <QtTest/QTest>
|
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN( NotificationMessageV2Test )
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testCompress()
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( NotificationMessageV2::Items );
|
||||||
|
msg.setOperation( NotificationMessageV2::Add );
|
||||||
|
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessageV2::Modify );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessageV2::Add );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessageV2::Remove );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 2 ); // should be 2 for collections, 0 for items?
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testCompress2()
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( NotificationMessageV2::Items );
|
||||||
|
msg.setOperation( NotificationMessageV2::Modify );
|
||||||
|
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessageV2::Remove );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessageV2::Remove );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testCompress3()
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( NotificationMessageV2::Items );
|
||||||
|
msg.setOperation( NotificationMessageV2::Modify );
|
||||||
|
msg.setItemParts( QSet<QByteArray>() << "PART1" );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
NotificationMessageV2 msg2;
|
||||||
|
msg2.setType( NotificationMessageV2::Items );
|
||||||
|
msg2.setOperation( NotificationMessageV2::Modify );
|
||||||
|
msg2.setItemParts( QSet<QByteArray>() << "PART2" );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg2 );
|
||||||
|
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().itemParts(), QSet<QByteArray>() << "PART1" << "PART2" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testCompress4()
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( NotificationMessageV2::Items );
|
||||||
|
msg.setOperation( NotificationMessageV2::ModifyFlags );
|
||||||
|
|
||||||
|
QSet<QByteArray> set;
|
||||||
|
set << "FLAG1";
|
||||||
|
msg.setAddedFlags( set );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
set.clear();
|
||||||
|
msg.setAddedFlags( set );
|
||||||
|
set << "FLAG2";
|
||||||
|
msg.setRemovedFlags( set );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().addedFlags(), ( QSet<QByteArray>() << "FLAG1" ) );
|
||||||
|
QCOMPARE( list.first().removedFlags(), ( QSet<QByteArray>() << "FLAG2" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testCompress5()
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( NotificationMessageV2::Items );
|
||||||
|
msg.setOperation( NotificationMessageV2::ModifyFlags );
|
||||||
|
|
||||||
|
msg.setAddedFlags( QSet<QByteArray>() << "FLAG1" << "FLAG2" );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
NotificationMessageV2 msg2;
|
||||||
|
msg2.setType( NotificationMessageV2::Items );
|
||||||
|
msg2.setOperation( NotificationMessageV2::Add );
|
||||||
|
msg2.setAddedFlags( QSet<QByteArray>() );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg2 );
|
||||||
|
|
||||||
|
msg.setAddedFlags( QSet<QByteArray>() );
|
||||||
|
msg.setRemovedFlags( QSet<QByteArray>() << "FLAG2" << "FLAG1" );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessageV2::Add );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testCompress6()
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( NotificationMessageV2::Items );
|
||||||
|
msg.setOperation( NotificationMessageV2::ModifyFlags );
|
||||||
|
msg.setAddedFlags( QSet<QByteArray>() << "FLAG1" );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
NotificationMessageV2 msg2;
|
||||||
|
msg2.setType( NotificationMessageV2::Items );
|
||||||
|
msg2.setOperation( NotificationMessageV2::ModifyFlags );
|
||||||
|
msg2.setAddedFlags( QSet<QByteArray>() << "FLAG2" );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg2 );
|
||||||
|
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessageV2::ModifyFlags );
|
||||||
|
QCOMPARE( list.first().addedFlags(), QSet<QByteArray>() << "FLAG1" << "FLAG2" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testCompress7()
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( NotificationMessageV2::Items );
|
||||||
|
msg.setOperation( NotificationMessageV2::Modify );
|
||||||
|
msg.setItemParts( QSet<QByteArray>() << "PART1" );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
NotificationMessageV2 msg2;
|
||||||
|
msg2.setType( NotificationMessageV2::Items );
|
||||||
|
msg2.setOperation( NotificationMessageV2::ModifyFlags );
|
||||||
|
msg2.setAddedFlags( QSet<QByteArray>() << "FLAG1" );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg2 );
|
||||||
|
|
||||||
|
QCOMPARE( list.count(), 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testCompressWithItemParts()
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( NotificationMessageV2::Items );
|
||||||
|
msg.setOperation( NotificationMessageV2::Add );
|
||||||
|
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessageV2::Modify );
|
||||||
|
QSet<QByteArray> parts;
|
||||||
|
parts << "SomePart";
|
||||||
|
msg.setAddedFlags( parts );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessageV2::Add );
|
||||||
|
QCOMPARE( list.first().itemParts(), QSet<QByteArray>() );
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setOperation( NotificationMessageV2::Remove );
|
||||||
|
msg.setItemParts( QSet<QByteArray>() );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().operation(), NotificationMessageV2::Remove );
|
||||||
|
QCOMPARE( list.first().itemParts(), QSet<QByteArray>() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testNoCompress()
|
||||||
|
{
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( NotificationMessageV2::Items );
|
||||||
|
msg.setOperation( NotificationMessageV2::Modify );
|
||||||
|
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setType( NotificationMessageV2::Collections );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testPartModificationMerge_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<NotificationMessageV2::Type>( "type" );
|
||||||
|
QTest::newRow( "item" ) << NotificationMessageV2::Items;
|
||||||
|
QTest::newRow( "collection" ) << NotificationMessageV2::Collections;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationMessageV2Test::testPartModificationMerge()
|
||||||
|
{
|
||||||
|
QFETCH( NotificationMessageV2::Type, type );
|
||||||
|
|
||||||
|
NotificationMessageV2::List list;
|
||||||
|
NotificationMessageV2 msg;
|
||||||
|
msg.setType( type );
|
||||||
|
msg.setOperation( NotificationMessageV2::Modify );
|
||||||
|
msg.setItemParts( QSet<QByteArray>() << "PART1" );
|
||||||
|
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
|
||||||
|
msg.setItemParts( QSet<QByteArray>() << "PART2" );
|
||||||
|
NotificationMessageV2::appendAndCompress( list, msg );
|
||||||
|
QCOMPARE( list.count(), 1 );
|
||||||
|
QCOMPARE( list.first().itemParts(), ( QSet<QByteArray>() << "PART1" << "PART2" ) );
|
||||||
|
}
|
43
akonadi/libs/tests/notificationmessagev2test.h
Normal file
43
akonadi/libs/tests/notificationmessagev2test.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Volker Krause <vkrause@kde.org>
|
||||||
|
Copyright (c) 2013 Daniel Vrátil <dvratil@redhat.com>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Library General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AKONADI_NOTIFICATIONMESSAGEV2TEST_H
|
||||||
|
#define AKONADI_NOTIFICATIONMESSAGEV2TEST_H
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
class NotificationMessageV2Test : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private Q_SLOTS:
|
||||||
|
void testCompress();
|
||||||
|
void testCompress2();
|
||||||
|
void testCompress3();
|
||||||
|
void testCompress4();
|
||||||
|
void testCompress5();
|
||||||
|
void testCompress6();
|
||||||
|
void testCompress7();
|
||||||
|
void testCompressWithItemParts();
|
||||||
|
void testNoCompress();
|
||||||
|
void testPartModificationMerge_data();
|
||||||
|
void testPartModificationMerge();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
501
akonadi/libs/xdgbasedirs.cpp
Normal file
501
akonadi/libs/xdgbasedirs.cpp
Normal file
|
@ -0,0 +1,501 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Kevin Krammer <kevin.krammer@gmx.at> *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Library General Public License as *
|
||||||
|
* published by the Free Software Foundation; either version 2 of the *
|
||||||
|
* License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public *
|
||||||
|
* License along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "xdgbasedirs_p.h"
|
||||||
|
|
||||||
|
#include "akonadi-prefix.h" // for prefix defines
|
||||||
|
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtCore/QProcess>
|
||||||
|
#include <QtCore/QSettings>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
static QStringList alternateExecPaths( const QString &path )
|
||||||
|
{
|
||||||
|
QStringList pathList;
|
||||||
|
|
||||||
|
pathList << path;
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN) //krazy:exclude=cpp
|
||||||
|
pathList << path + QLatin1String( ".exe" );
|
||||||
|
#elif defined(Q_OS_MAC) //krazy:exclude=cpp
|
||||||
|
pathList << path + QLatin1String( ".app/Contents/MacOS/" ) + path.section( QLatin1Char( '/' ), -1 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return pathList;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QStringList splitPathList( const QString &pathList )
|
||||||
|
{
|
||||||
|
#if defined(Q_OS_WIN) //krazy:exclude=cpp
|
||||||
|
return pathList.split( QLatin1Char( ';' ) );
|
||||||
|
#else
|
||||||
|
return pathList.split( QLatin1Char( ':' ) );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Akonadi {
|
||||||
|
|
||||||
|
class XdgBaseDirsPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XdgBaseDirsPrivate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~XdgBaseDirsPrivate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class XdgBaseDirsSingleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString homePath( const char *variable, const char *defaultSubDir );
|
||||||
|
|
||||||
|
QStringList systemPathList( const char *variable, const char *defaultDirList );
|
||||||
|
|
||||||
|
public:
|
||||||
|
QString mConfigHome;
|
||||||
|
QString mDataHome;
|
||||||
|
|
||||||
|
QStringList mConfigDirs;
|
||||||
|
QStringList mDataDirs;
|
||||||
|
QStringList mExecutableDirs;
|
||||||
|
QStringList mPluginDirs;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC( XdgBaseDirsSingleton, instance )
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Akonadi;
|
||||||
|
|
||||||
|
XdgBaseDirs::XdgBaseDirs()
|
||||||
|
: d( new XdgBaseDirsPrivate() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
XdgBaseDirs::~XdgBaseDirs()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirs::homePath( const char *resource )
|
||||||
|
{
|
||||||
|
if ( qstrncmp( "data", resource, 4 ) == 0 ) {
|
||||||
|
if ( instance()->mDataHome.isEmpty() ) {
|
||||||
|
instance()->mDataHome = instance()->homePath( "XDG_DATA_HOME", ".local/share" );
|
||||||
|
}
|
||||||
|
return instance()->mDataHome;
|
||||||
|
} else if ( qstrncmp( "config", resource, 6 ) == 0 ) {
|
||||||
|
if ( instance()->mConfigHome.isEmpty() ) {
|
||||||
|
instance()->mConfigHome = instance()->homePath( "XDG_CONFIG_HOME", ".config" );
|
||||||
|
}
|
||||||
|
return instance()->mConfigHome;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList XdgBaseDirs::systemPathList( const char *resource )
|
||||||
|
{
|
||||||
|
if ( qstrncmp( "data", resource, 4 ) == 0 ) {
|
||||||
|
if ( instance()->mDataDirs.isEmpty() ) {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QDir dir( QCoreApplication::applicationDirPath() );
|
||||||
|
dir.cdUp();
|
||||||
|
const QString defaultPathList = dir.absoluteFilePath( QLatin1String( "share" ) );
|
||||||
|
QStringList dataDirs = instance()->systemPathList( "XDG_DATA_DIRS", defaultPathList.toLocal8Bit().constData() );
|
||||||
|
#else
|
||||||
|
QStringList dataDirs = instance()->systemPathList( "XDG_DATA_DIRS", "/usr/local/share:/usr/share" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
const QString prefixDataDir = QLatin1String( AKONADIPREFIX "/" AKONADIDATA );
|
||||||
|
#else
|
||||||
|
const QString prefixDataDir = QLatin1String( AKONADIDATA );
|
||||||
|
#endif
|
||||||
|
if ( !dataDirs.contains( prefixDataDir ) ) {
|
||||||
|
dataDirs << prefixDataDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < 0x050000
|
||||||
|
// fallback for users with KDE in a different prefix and not correctly set up XDG_DATA_DIRS, hi David ;-)
|
||||||
|
QProcess proc;
|
||||||
|
// ### should probably rather be --path xdg-something
|
||||||
|
const QStringList args = QStringList() << QLatin1String( "--prefix" );
|
||||||
|
proc.start( QLatin1String( "kde4-config" ), args );
|
||||||
|
if ( proc.waitForStarted() && proc.waitForFinished() && proc.exitCode() == 0 ) {
|
||||||
|
proc.setReadChannel( QProcess::StandardOutput );
|
||||||
|
Q_FOREACH ( const QString &basePath, splitPathList( QString::fromLocal8Bit( proc.readLine().trimmed() ) ) ) {
|
||||||
|
const QString path = basePath + QDir::separator() + QLatin1String( "share" );
|
||||||
|
if ( !dataDirs.contains( path ) ) {
|
||||||
|
dataDirs << path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
instance()->mDataDirs = dataDirs;
|
||||||
|
}
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QStringList dataDirs = instance()->mDataDirs;
|
||||||
|
// on Windows installation might be scattered across several directories
|
||||||
|
// so check if any installer providing agents has registered its base path
|
||||||
|
QSettings agentProviders( QSettings::SystemScope, QLatin1String( "Akonadi" ), QLatin1String( "Akonadi" ) );
|
||||||
|
agentProviders.beginGroup( QLatin1String( "AgentProviders" ) );
|
||||||
|
Q_FOREACH ( const QString &agentProvider, agentProviders.childKeys() ) {
|
||||||
|
const QString basePath = agentProviders.value( agentProvider ).toString();
|
||||||
|
if ( !basePath.isEmpty() ) {
|
||||||
|
const QString path = basePath + QDir::separator() + QLatin1String( "share" );
|
||||||
|
if ( !dataDirs.contains( path ) ) {
|
||||||
|
dataDirs << path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataDirs;
|
||||||
|
#else
|
||||||
|
return instance()->mDataDirs;
|
||||||
|
#endif
|
||||||
|
} else if ( qstrncmp( "config", resource, 6 ) == 0 ) {
|
||||||
|
if ( instance()->mConfigDirs.isEmpty() ) {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QDir dir( QCoreApplication::applicationDirPath() );
|
||||||
|
dir.cdUp();
|
||||||
|
const QString defaultPathList = dir.absoluteFilePath( QLatin1String( "etc" ) ) + QLatin1Char( ';' ) + dir.absoluteFilePath( QLatin1String( "share/config" ) );
|
||||||
|
QStringList configDirs = instance()->systemPathList( "XDG_CONFIG_DIRS", defaultPathList.toLocal8Bit().constData() );
|
||||||
|
#else
|
||||||
|
QStringList configDirs = instance()->systemPathList( "XDG_CONFIG_DIRS", "/etc/xdg" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
const QString prefixConfigDir = QLatin1String( AKONADIPREFIX "/" AKONADICONFIG );
|
||||||
|
#else
|
||||||
|
const QString prefixConfigDir = QLatin1String( AKONADICONFIG );
|
||||||
|
#endif
|
||||||
|
if ( !configDirs.contains( prefixConfigDir ) ) {
|
||||||
|
configDirs << prefixConfigDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance()->mConfigDirs = configDirs;
|
||||||
|
}
|
||||||
|
return instance()->mConfigDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirs::findResourceFile( const char *resource, const QString &relPath )
|
||||||
|
{
|
||||||
|
const QString fullPath = homePath( resource ) + QLatin1Char( '/' ) + relPath;
|
||||||
|
|
||||||
|
QFileInfo fileInfo( fullPath );
|
||||||
|
if ( fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable() ) {
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QStringList pathList = systemPathList( resource );
|
||||||
|
|
||||||
|
Q_FOREACH ( const QString &path, pathList ) {
|
||||||
|
fileInfo = QFileInfo( path + QLatin1Char( '/' ) + relPath );
|
||||||
|
if ( fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable() ) {
|
||||||
|
return fileInfo.absoluteFilePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirs::findExecutableFile( const QString &relPath, const QStringList &searchPath )
|
||||||
|
{
|
||||||
|
if ( instance()->mExecutableDirs.isEmpty() ) {
|
||||||
|
QStringList executableDirs = instance()->systemPathList( "PATH", "/usr/local/bin:/usr/bin" );
|
||||||
|
|
||||||
|
const QString prefixExecutableDir = QLatin1String( AKONADIPREFIX "/bin" );
|
||||||
|
if ( !executableDirs.contains( prefixExecutableDir ) ) {
|
||||||
|
executableDirs << prefixExecutableDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( QCoreApplication::instance() != 0 ) {
|
||||||
|
const QString appExecutableDir = QCoreApplication::instance()->applicationDirPath();
|
||||||
|
if ( !executableDirs.contains( appExecutableDir ) ) {
|
||||||
|
executableDirs << appExecutableDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
executableDirs += searchPath;
|
||||||
|
|
||||||
|
#if defined(Q_OS_MAC) //krazy:exclude=cpp
|
||||||
|
executableDirs += QLatin1String( AKONADIBUNDLEPATH );
|
||||||
|
#endif
|
||||||
|
qWarning() << "search paths: " << executableDirs;
|
||||||
|
|
||||||
|
instance()->mExecutableDirs = executableDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QStringList executableDirs = instance()->mExecutableDirs;
|
||||||
|
// on Windows installation might be scattered across several directories
|
||||||
|
// so check if any installer providing agents has registered its base path
|
||||||
|
QSettings agentProviders( QSettings::SystemScope, QLatin1String( "Akonadi" ), QLatin1String( "Akonadi" ) );
|
||||||
|
agentProviders.beginGroup( QLatin1String( "AgentProviders" ) );
|
||||||
|
Q_FOREACH ( const QString &agentProvider, agentProviders.childKeys() ) {
|
||||||
|
const QString basePath = agentProviders.value( agentProvider ).toString();
|
||||||
|
if ( !basePath.isEmpty() ) {
|
||||||
|
const QString path = basePath + QDir::separator() + QLatin1String( "bin" );
|
||||||
|
if ( !executableDirs.contains( path ) ) {
|
||||||
|
executableDirs << path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList::const_iterator pathIt = executableDirs.constBegin();
|
||||||
|
const QStringList::const_iterator pathEndIt = executableDirs.constEnd();
|
||||||
|
#else
|
||||||
|
QStringList::const_iterator pathIt = instance()->mExecutableDirs.constBegin();
|
||||||
|
const QStringList::const_iterator pathEndIt = instance()->mExecutableDirs.constEnd();
|
||||||
|
#endif
|
||||||
|
for ( ; pathIt != pathEndIt; ++pathIt ) {
|
||||||
|
const QStringList fullPathList = alternateExecPaths( *pathIt + QLatin1Char( '/' ) + relPath );
|
||||||
|
|
||||||
|
QStringList::const_iterator it = fullPathList.constBegin();
|
||||||
|
const QStringList::const_iterator endIt = fullPathList.constEnd();
|
||||||
|
for ( ; it != endIt; ++it ) {
|
||||||
|
const QFileInfo fileInfo( *it );
|
||||||
|
|
||||||
|
// resolve symlinks, happens eg. with Maemo optify
|
||||||
|
if ( fileInfo.canonicalFilePath().isEmpty() ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QFileInfo canonicalFileInfo( fileInfo.canonicalFilePath() );
|
||||||
|
|
||||||
|
if ( canonicalFileInfo.exists() && canonicalFileInfo.isFile() && canonicalFileInfo.isExecutable() ) {
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList XdgBaseDirs::findPluginDirs()
|
||||||
|
{
|
||||||
|
if ( instance()->mPluginDirs.isEmpty() ) {
|
||||||
|
QStringList pluginDirs = instance()->systemPathList( "QT_PLUGIN_PATH", AKONADILIB ":" AKONADILIB "/qt4/plugins/:" AKONADILIB "/kde4/:" AKONADILIB "/kde4/plugins/:/usr/lib/qt4/plugins/" );
|
||||||
|
|
||||||
|
if ( QCoreApplication::instance() != 0 ) {
|
||||||
|
Q_FOREACH ( const QString &libraryPath, QCoreApplication::instance()->libraryPaths() ) {
|
||||||
|
if ( !pluginDirs.contains( libraryPath ) ) {
|
||||||
|
pluginDirs << libraryPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback for users with KDE in a different prefix and not correctly set up XDG_DATA_DIRS, hi David ;-)
|
||||||
|
QProcess proc;
|
||||||
|
// ### should probably rather be --path xdg-something
|
||||||
|
const QStringList args = QStringList() << QLatin1String( "--path" ) << QLatin1String( "module" );
|
||||||
|
proc.start( QLatin1String( "kde4-config" ), args );
|
||||||
|
if ( proc.waitForStarted() && proc.waitForFinished() && proc.exitCode() == 0 ) {
|
||||||
|
proc.setReadChannel( QProcess::StandardOutput );
|
||||||
|
Q_FOREACH ( const QString &path, splitPathList( QString::fromLocal8Bit( proc.readLine().trimmed() ) ) ) {
|
||||||
|
if ( !pluginDirs.contains( path ) ) {
|
||||||
|
pluginDirs.append( path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qWarning() << "search paths: " << pluginDirs;
|
||||||
|
instance()->mPluginDirs = pluginDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance()->mPluginDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirs::findPluginFile( const QString &relPath, const QStringList &searchPath )
|
||||||
|
{
|
||||||
|
const QStringList searchDirs = findPluginDirs() + searchPath;
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN) //krazy:exclude=cpp
|
||||||
|
const QString pluginName = relPath + QLatin1String( ".dll" );
|
||||||
|
#else
|
||||||
|
const QString pluginName = relPath + QLatin1String( ".so" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Q_FOREACH ( const QString &path, searchDirs ) {
|
||||||
|
const QFileInfo fileInfo( path + QDir::separator() + pluginName );
|
||||||
|
|
||||||
|
// resolve symlinks, happens eg. with Maemo optify
|
||||||
|
if ( fileInfo.canonicalFilePath().isEmpty() ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QFileInfo canonicalFileInfo( fileInfo.canonicalFilePath() );
|
||||||
|
if ( canonicalFileInfo.exists() && canonicalFileInfo.isFile() ) {
|
||||||
|
return canonicalFileInfo.absoluteFilePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirs::findResourceDir( const char *resource, const QString &relPath )
|
||||||
|
{
|
||||||
|
QString fullPath = homePath( resource ) + QLatin1Char( '/' ) + relPath;
|
||||||
|
|
||||||
|
QFileInfo fileInfo( fullPath );
|
||||||
|
if ( fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable() ) {
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_FOREACH ( const QString &path, systemPathList( resource ) ) {
|
||||||
|
fileInfo = QFileInfo( path + QLatin1Char( '/' ) + relPath );
|
||||||
|
if ( fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable() ) {
|
||||||
|
return fileInfo.absoluteFilePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList XdgBaseDirs::findAllResourceDirs( const char *resource, const QString &relPath )
|
||||||
|
{
|
||||||
|
QStringList resultList;
|
||||||
|
|
||||||
|
const QString fullPath = homePath( resource ) + QLatin1Char( '/' ) + relPath;
|
||||||
|
|
||||||
|
QFileInfo fileInfo( fullPath );
|
||||||
|
if ( fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable() ) {
|
||||||
|
resultList << fileInfo.absoluteFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_FOREACH ( const QString &path, systemPathList( resource ) ) {
|
||||||
|
fileInfo = QFileInfo( path + QLatin1Char( '/' ) + relPath );
|
||||||
|
if ( fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable() ) {
|
||||||
|
const QString absPath = fileInfo.absoluteFilePath();
|
||||||
|
if ( !resultList.contains( absPath ) ) {
|
||||||
|
resultList << absPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirs::saveDir( const char *resource, const QString &relPath )
|
||||||
|
{
|
||||||
|
const QString fullPath = homePath( resource ) + QLatin1Char( '/' ) + relPath;
|
||||||
|
|
||||||
|
QFileInfo fileInfo( fullPath );
|
||||||
|
if ( fileInfo.exists() ) {
|
||||||
|
if ( fileInfo.isDir() ) {
|
||||||
|
return fullPath;
|
||||||
|
} else {
|
||||||
|
qWarning() << "XdgBaseDirs::saveDir: '" << fileInfo.absoluteFilePath()
|
||||||
|
<< "' exists but is not a directory";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( !QDir::home().mkpath( fileInfo.absoluteFilePath() ) ) {
|
||||||
|
qWarning() << "XdgBaseDirs::saveDir: failed to create directory '"
|
||||||
|
<< fileInfo.absoluteFilePath() << "'";
|
||||||
|
} else {
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirs::akonadiServerConfigFile( FileAccessMode openMode )
|
||||||
|
{
|
||||||
|
return akonadiConfigFile( QLatin1String( "akonadiserverrc" ), openMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirs::akonadiConnectionConfigFile( FileAccessMode openMode )
|
||||||
|
{
|
||||||
|
return akonadiConfigFile( QLatin1String( "akonadiconnectionrc" ), openMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirs::akonadiConfigFile( const QString &file, FileAccessMode openMode )
|
||||||
|
{
|
||||||
|
const QString akonadiDir = QLatin1String( "akonadi" );
|
||||||
|
|
||||||
|
const QString savePath = saveDir( "config", akonadiDir ) + QLatin1Char( '/' ) + file;
|
||||||
|
|
||||||
|
if ( openMode == WriteOnly ) {
|
||||||
|
return savePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString path = findResourceFile( "config", akonadiDir + QLatin1Char( '/' ) + file );
|
||||||
|
|
||||||
|
if ( path.isEmpty() ) {
|
||||||
|
return savePath;
|
||||||
|
} else if ( openMode == ReadOnly || path == savePath ) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// file found in system paths and mode is ReadWrite, thus
|
||||||
|
// we copy to the home path location and return this path
|
||||||
|
QFile systemFile( path );
|
||||||
|
|
||||||
|
systemFile.copy( savePath );
|
||||||
|
|
||||||
|
return savePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XdgBaseDirsSingleton::homePath( const char *variable, const char *defaultSubDir )
|
||||||
|
{
|
||||||
|
const QByteArray env = qgetenv( variable );
|
||||||
|
|
||||||
|
QString xdgPath;
|
||||||
|
if ( env.isEmpty() ) {
|
||||||
|
xdgPath = QDir::homePath() + QLatin1Char( '/' ) + QLatin1String( defaultSubDir );
|
||||||
|
#if defined(Q_OS_WIN) //krazy:exclude=cpp
|
||||||
|
} else if ( QDir::isAbsolutePath( QString::fromLocal8Bit( env ) ) ) {
|
||||||
|
#else
|
||||||
|
} else if ( env.startsWith( '/' ) ) {
|
||||||
|
#endif
|
||||||
|
xdgPath = QString::fromLocal8Bit( env );
|
||||||
|
} else {
|
||||||
|
xdgPath = QDir::homePath() + QLatin1Char( '/' ) + QString::fromLocal8Bit( env );
|
||||||
|
}
|
||||||
|
|
||||||
|
return xdgPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList XdgBaseDirsSingleton::systemPathList( const char *variable, const char *defaultDirList )
|
||||||
|
{
|
||||||
|
const QByteArray env = qgetenv( variable );
|
||||||
|
|
||||||
|
QString xdgDirList;
|
||||||
|
if ( env.isEmpty() ) {
|
||||||
|
xdgDirList = QLatin1String( defaultDirList );
|
||||||
|
} else {
|
||||||
|
xdgDirList = QString::fromLocal8Bit( env );
|
||||||
|
}
|
||||||
|
|
||||||
|
return splitPathList( xdgDirList );
|
||||||
|
}
|
322
akonadi/libs/xdgbasedirs_p.h
Normal file
322
akonadi/libs/xdgbasedirs_p.h
Normal file
|
@ -0,0 +1,322 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007 by Kevin Krammer <kevin.krammer@gmx.at> *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Library General Public License as *
|
||||||
|
* published by the Free Software Foundation; either version 2 of the *
|
||||||
|
* License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public *
|
||||||
|
* License along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef XDGBASEDIRS_H
|
||||||
|
#define XDGBASEDIRS_H
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QFlags>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
|
#include "akonadiprotocolinternals_export.h"
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
namespace Akonadi {
|
||||||
|
|
||||||
|
class XdgBaseDirsPrivate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Resource type based handling of standard directories
|
||||||
|
|
||||||
|
Developers of several Free Software desktop projects have created
|
||||||
|
a specification for handling so-called "base directories", i.e.
|
||||||
|
lists of system wide directories and directories within each user's
|
||||||
|
home directory for installing and later finding certain files.
|
||||||
|
|
||||||
|
This class handles the respective behaviour, i.e. environment variables
|
||||||
|
and their defaults, for the following type of resources:
|
||||||
|
- "config"
|
||||||
|
- "data"
|
||||||
|
|
||||||
|
Example: getting the Akonadi server config file "akonadiserverrc", assuming
|
||||||
|
that Akonadi stores its config in an additional subdirectoy called "akonadi"
|
||||||
|
@code
|
||||||
|
QString relativeFileName = QLatin1String( "akonadi/akonadiserverrc" );
|
||||||
|
|
||||||
|
// look for the file "akonadiserverrc" with additional subdirectory "akonadi"
|
||||||
|
// in any directory associated with resource type "config"
|
||||||
|
QString configFile = XdgBaseDirs::findResourceFile( "config", relativeFileName );
|
||||||
|
|
||||||
|
if ( configFile.isEmpty() ) {
|
||||||
|
// No config file yet, get the suitable user specific directory for storing
|
||||||
|
// a new one
|
||||||
|
configFile = XdgBaseDirs::saveDir( "config", QLatin1String( "akonadi" ) );
|
||||||
|
configFile += QLatin1String( "akonadiserverrc" );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSettings serverConfig( configFile );
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@author Kevin Krammer, <kevin.krammer@gmx.at>
|
||||||
|
|
||||||
|
@see http://www.freedesktop.org/wiki/Specifications/basedir-spec
|
||||||
|
*/
|
||||||
|
class AKONADIPROTOCOLINTERNALS_EXPORT XdgBaseDirs
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
@brief Creates the instance
|
||||||
|
*/
|
||||||
|
XdgBaseDirs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Destroys the instance
|
||||||
|
*/
|
||||||
|
~XdgBaseDirs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Returns the user specific directory for the given resource type
|
||||||
|
|
||||||
|
Unless the user's environment has a specific path set as an override
|
||||||
|
this will be the default as defined in the freedesktop.org base-dir-spec
|
||||||
|
|
||||||
|
@note Caches the value of the first call
|
||||||
|
|
||||||
|
@param resource a named resource type, e.g. "config"
|
||||||
|
|
||||||
|
@return a directory path
|
||||||
|
|
||||||
|
@see systemPathList()
|
||||||
|
@see saveDir()
|
||||||
|
*/
|
||||||
|
static QString homePath( const char *resource );
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Returns the list of system wide directories for a given resource type
|
||||||
|
|
||||||
|
The returned list can contain one or more directory paths. If there are more
|
||||||
|
than one, the list is sorted by falling priority, i.e. if an entry is valid
|
||||||
|
for the respective use case (e.g. contains a file the application looks for)
|
||||||
|
the list should not be processed further.
|
||||||
|
|
||||||
|
@note The user's resource path should, to be compliant with the spec,
|
||||||
|
always be treated as having higher priority than any path in the
|
||||||
|
list of system wide paths
|
||||||
|
|
||||||
|
@note Caches the value of the first call
|
||||||
|
|
||||||
|
@param resource a named resource type, e.g. "config"
|
||||||
|
|
||||||
|
@return a priority sorted list of directory paths
|
||||||
|
|
||||||
|
@see homePath()
|
||||||
|
*/
|
||||||
|
static QStringList systemPathList( const char *resource );
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Searches the resource specific directories for a given file
|
||||||
|
|
||||||
|
Convenience method for finding a given file (with optional relative path)
|
||||||
|
in any of the configured base directories for a given resource type.
|
||||||
|
|
||||||
|
Will check the user local directory first and then process the system
|
||||||
|
wide path list according to the inherent priority.
|
||||||
|
|
||||||
|
@param resource a named resource type, e.g. "config"
|
||||||
|
@param relPath relative path of a file to look for,
|
||||||
|
e.g."akonadi/akonadiserverrc"
|
||||||
|
|
||||||
|
@returns the file path of the first match, or @c QString() if no such
|
||||||
|
relative path exists in any of the base directories or if
|
||||||
|
a match is not a file
|
||||||
|
|
||||||
|
@see findResourceDir()
|
||||||
|
@see saveDir
|
||||||
|
*/
|
||||||
|
static QString findResourceFile( const char *resource, const QString &relPath );
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Searches the executable specific directories for a given file
|
||||||
|
|
||||||
|
Convenience method for finding a given executable (with optional relative path)
|
||||||
|
in any of the configured directories for a this special type.
|
||||||
|
|
||||||
|
@note This is not based on the XDG base dir spec, since it does not cover
|
||||||
|
executable
|
||||||
|
|
||||||
|
@param relPath relative path of a file to look for,
|
||||||
|
e.g."akonadiserver"
|
||||||
|
@param searchPath additional paths to search for the executable,
|
||||||
|
only used if the file was not found in PATH and the install prefix
|
||||||
|
|
||||||
|
@returns the file path of the first match, or @c QString() if no such
|
||||||
|
relative path exists in any of the base directories
|
||||||
|
|
||||||
|
@see findResourceFile()
|
||||||
|
*/
|
||||||
|
static QString findExecutableFile( const QString &relPath, const QStringList &searchPath = QStringList() );
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Searches the plugin specific directories for a given file
|
||||||
|
|
||||||
|
Convenience method for finding a given plugin (with optional relative path)
|
||||||
|
in any of the configured directories for a this special type.
|
||||||
|
|
||||||
|
@note This is not based on the XDG base dir spec, since it does not cover
|
||||||
|
plugins
|
||||||
|
|
||||||
|
@param relPath relative path of a file to look for,
|
||||||
|
e.g."akonadi_knut_resource"
|
||||||
|
@param searchPath additional paths to search for the plugin,
|
||||||
|
only used if the file was not found in QT_PLUGIN_PATH and the install prefix
|
||||||
|
|
||||||
|
@returns the file path of the first match, or @c QString() if no such
|
||||||
|
relative path exists in any of the base directories
|
||||||
|
|
||||||
|
@see findResourceFile()
|
||||||
|
*/
|
||||||
|
static QString findPluginFile( const QString &relPath, const QStringList &searchPath = QStringList() );
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Returns plugin specific directories
|
||||||
|
|
||||||
|
Convenience method for listing directories that can be scanned for available
|
||||||
|
plugins.
|
||||||
|
|
||||||
|
@note This is not based on the XDG base dir spec, since it does not cover
|
||||||
|
plugins.
|
||||||
|
|
||||||
|
@return directories where application should look for plugins
|
||||||
|
*/
|
||||||
|
static QStringList findPluginDirs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Searches the resource specific directories for a given subdirectory
|
||||||
|
|
||||||
|
Convenience method for finding a given relative subdirectory in any of
|
||||||
|
the configured base directories for a given resource type.
|
||||||
|
|
||||||
|
Will check the user local directory first and then process the system
|
||||||
|
wide path list according to the inherent priority.
|
||||||
|
|
||||||
|
Use findAllResourceDirs() if looking for all directories with the given
|
||||||
|
subdirectory.
|
||||||
|
|
||||||
|
@param resource a named resource type, e.g. "config"
|
||||||
|
@param relPath relative path of a subdirectory to look for,
|
||||||
|
e.g."akonadi/agents"
|
||||||
|
|
||||||
|
@returns the directory path of the first match, or @c QString() if no such
|
||||||
|
relative path exists in any of the base directories or if
|
||||||
|
a match is not a directory
|
||||||
|
|
||||||
|
@see findResourceFile()
|
||||||
|
@see saveDir()
|
||||||
|
*/
|
||||||
|
static QString findResourceDir( const char *resource, const QString &relPath );
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Searches the resource specific directories for a given subdirectory
|
||||||
|
|
||||||
|
Convenience method for getting a list of directoreis with a given relative
|
||||||
|
subdirectory in any of the configured base directories for a given
|
||||||
|
resource type.
|
||||||
|
|
||||||
|
Will check the user local directory first and then process the system
|
||||||
|
wide path list according to the inherent priority.
|
||||||
|
|
||||||
|
Similar to findResourceDir() but does not just find the first best match
|
||||||
|
but all matching resource directories. The resuling list will be sorted
|
||||||
|
according to the same proprity criteria.
|
||||||
|
|
||||||
|
@param resource a named resource type, e.g. "config"
|
||||||
|
@param relPath relative path of a subdirectory to look for,
|
||||||
|
e.g."akonadi/agents"
|
||||||
|
|
||||||
|
@returns a list of directory paths, or @c QString() if no such
|
||||||
|
relative path exists in any of the base directories or if
|
||||||
|
non of the matches is a directory
|
||||||
|
|
||||||
|
@see findResourceDir()
|
||||||
|
*/
|
||||||
|
static QStringList findAllResourceDirs( const char *resource, const QString &relPath );
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Finds or creates the "save to" directory for a given resource
|
||||||
|
|
||||||
|
Convenience method for creating subdirectores relative to a given
|
||||||
|
resource type's user directory, i.e. homePath() + relPath
|
||||||
|
|
||||||
|
If the target directory does not exists, it an all necessary parent
|
||||||
|
directories will be created, unless denied by the filesystem.
|
||||||
|
|
||||||
|
@param resource a named resource type, e.g. "config"
|
||||||
|
@param relPath relative path of a directory to be used for file writing
|
||||||
|
|
||||||
|
@return the directory path of the "save to" directory or @c QString()
|
||||||
|
if the directory or one of its parents could not be created
|
||||||
|
|
||||||
|
@see findResourceDir()
|
||||||
|
*/
|
||||||
|
static QString saveDir( const char *resource, const QString &relPath );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Open mode flags for resource files
|
||||||
|
*
|
||||||
|
* FileAccessMode is a typedef for QFlags<FileAccessFlag>. It stores
|
||||||
|
* a OR combination of FileAccessFlag values
|
||||||
|
*/
|
||||||
|
enum FileAccessFlag {
|
||||||
|
ReadOnly = 0x1,
|
||||||
|
WriteOnly = 0x2,
|
||||||
|
ReadWrite = ReadOnly | WriteOnly
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef QFlags<FileAccessFlag> FileAccessMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the path of the Akonadi server config file
|
||||||
|
*
|
||||||
|
* Convenience method for getting the server config file "akonadiserverrc"
|
||||||
|
* since this is an often needed procedure in several parts of the code.
|
||||||
|
*
|
||||||
|
* @param openMode how the application wants to use the config file
|
||||||
|
*
|
||||||
|
* @return the path of the server config file, suitable for \p openMode
|
||||||
|
*/
|
||||||
|
static QString akonadiServerConfigFile( FileAccessMode openMode = ReadOnly );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the path of the Akonadi data connection config file
|
||||||
|
*
|
||||||
|
* Convenience method for getting the server config file "akonadiconnectionrc"
|
||||||
|
* since this is an often needed procedure in several parts of the code.
|
||||||
|
*
|
||||||
|
* @param openMode how the application wants to use the config file
|
||||||
|
*
|
||||||
|
* @return the path of the data connection config file, suitable for \p openMode
|
||||||
|
*/
|
||||||
|
static QString akonadiConnectionConfigFile( FileAccessMode openMode = ReadOnly );
|
||||||
|
|
||||||
|
private:
|
||||||
|
XdgBaseDirsPrivate *const d;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QString akonadiConfigFile( const QString &file, FileAccessMode openMode );
|
||||||
|
|
||||||
|
private:
|
||||||
|
XdgBaseDirs( const XdgBaseDirs & );
|
||||||
|
XdgBaseDirs &operator=( const XdgBaseDirs & );
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
1
akonadi/qsqlite/.no_coding_style
Normal file
1
akonadi/qsqlite/.no_coding_style
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# this directory will not be tested.
|
46
akonadi/qsqlite/CMakeLists.txt
Normal file
46
akonadi/qsqlite/CMakeLists.txt
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
set(QSqlite_SRCS
|
||||||
|
src/sqlite_blocking.cpp
|
||||||
|
src/qsql_sqlite.cpp
|
||||||
|
src/smain.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
message(STATUS "Building QSQLITE3 driver")
|
||||||
|
|
||||||
|
if(INSTALL_QSQLITE_IN_QT_PREFIX)
|
||||||
|
set(QSQLITE_INSTALL_PREFIX "${QT_PLUGINS_DIR}/sqldrivers")
|
||||||
|
else()
|
||||||
|
set(QSQLITE_INSTALL_PREFIX "${LIB_INSTALL_DIR}/plugins/sqldrivers")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-Wall)
|
||||||
|
add_definitions(${QT_DEFINITIONS})
|
||||||
|
add_definitions(-DQT_PLUGIN)
|
||||||
|
add_definitions(-DQT_SHARED)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
|
${SQLITE_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(AKONADI_STATIC_SQLITE)
|
||||||
|
add_definitions(-DQT_STATICPLUGIN)
|
||||||
|
add_library(qsqlite3 STATIC ${QSqlite_SRCS} ${QSqlite_MOC_SRCS})
|
||||||
|
else()
|
||||||
|
add_library(qsqlite3 SHARED ${QSqlite_SRCS} ${QSqlite_MOC_SRCS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(qsqlite3 ${QT_QTCORE_LIBRARY} ${QT_QTSQL_LIBRARY})
|
||||||
|
|
||||||
|
if(SQLITE_LINK_STATIC)
|
||||||
|
message(STATUS "SQlite ${SQLITE_STATIC_LIBRARIES}")
|
||||||
|
target_link_libraries(qsqlite3 ${SQLITE_STATIC_LIBRARIES})
|
||||||
|
else()
|
||||||
|
message(STATUS "SQlite ${SQLITE_LIBRARIES}")
|
||||||
|
target_link_libraries(qsqlite3 ${SQLITE_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
INSTALL(TARGETS qsqlite3
|
||||||
|
RUNTIME DESTINATION ${QSQLITE_INSTALL_PREFIX}
|
||||||
|
LIBRARY DESTINATION ${QSQLITE_INSTALL_PREFIX}
|
||||||
|
ARCHIVE DESTINATION ${QSQLITE_INSTALL_PREFIX}
|
||||||
|
)
|
3
akonadi/qsqlite/README
Normal file
3
akonadi/qsqlite/README
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
This is a sliglty adjusted version of the QSQLITE driver. Install this driver
|
||||||
|
somewhere in the QT_PLUGIN_PATH and use it in akonadi by setting the driver
|
||||||
|
to QSQLITE3.
|
100
akonadi/qsqlite/src/QtSql/private/qsqlcachedresult_p.h
Normal file
100
akonadi/qsqlite/src/QtSql/private/qsqlcachedresult_p.h
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** All rights reserved.
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the QtSql module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial Usage
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#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 "QtSql/qsqlresult.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QVariant;
|
||||||
|
template <typename T> class QVector;
|
||||||
|
|
||||||
|
class QSqlCachedResultPrivate;
|
||||||
|
|
||||||
|
class Q_SQL_EXPORT QSqlCachedResult: public QSqlResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~QSqlCachedResult();
|
||||||
|
|
||||||
|
typedef QVector<QVariant> ValueCache;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QSqlCachedResult(const QSqlDriver * db);
|
||||||
|
|
||||||
|
void init(int colCount);
|
||||||
|
void cleanup();
|
||||||
|
void clearValues();
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
void virtual_hook(int id, void *data);
|
||||||
|
private:
|
||||||
|
bool cacheNext();
|
||||||
|
QSqlCachedResultPrivate *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QSQLCACHEDRESULT_P_H
|
724
akonadi/qsqlite/src/qsql_sqlite.cpp
Normal file
724
akonadi/qsqlite/src/qsql_sqlite.cpp
Normal file
|
@ -0,0 +1,724 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the QtSql module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial Usage
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qsql_sqlite.h"
|
||||||
|
|
||||||
|
#include <qcoreapplication.h>
|
||||||
|
#include <qvariant.h>
|
||||||
|
#include <qsqlerror.h>
|
||||||
|
#include <qsqlfield.h>
|
||||||
|
#include <qsqlindex.h>
|
||||||
|
#include <qsqlquery.h>
|
||||||
|
#include <qstringlist.h>
|
||||||
|
#include <qvector.h>
|
||||||
|
#include <qdebug.h>
|
||||||
|
|
||||||
|
#if defined Q_OS_WIN
|
||||||
|
# include <qt_windows.h>
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
#include <qthread.h>
|
||||||
|
#include "sqlite_blocking.h"
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(sqlite3*)
|
||||||
|
Q_DECLARE_METATYPE(sqlite3_stmt*)
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
static QString _q_escapeIdentifier(const QString &identifier)
|
||||||
|
{
|
||||||
|
QString res = identifier;
|
||||||
|
if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
|
||||||
|
res.replace(QLatin1Char('"'), QLatin1String("\"\""));
|
||||||
|
res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
|
||||||
|
res.replace(QLatin1Char('.'), QLatin1String("\".\""));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QVariant::Type qGetColumnType(const QString &tpName)
|
||||||
|
{
|
||||||
|
const QString typeName = tpName.toLower();
|
||||||
|
|
||||||
|
if (typeName == QLatin1String("integer")
|
||||||
|
|| typeName == QLatin1String("int"))
|
||||||
|
return QVariant::Int;
|
||||||
|
if (typeName == QLatin1String("double")
|
||||||
|
|| typeName == QLatin1String("float")
|
||||||
|
|| typeName.startsWith(QLatin1String("numeric")))
|
||||||
|
return QVariant::Double;
|
||||||
|
if (typeName == QLatin1String("blob"))
|
||||||
|
return QVariant::ByteArray;
|
||||||
|
return QVariant::String;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QSqlError qMakeError(sqlite3 *access, const QString &descr, QSqlError::ErrorType type,
|
||||||
|
int errorCode = -1)
|
||||||
|
{
|
||||||
|
return QSqlError(descr,
|
||||||
|
QString::fromUtf16(static_cast<const ushort *>(sqlite3_errmsg16(access))),
|
||||||
|
type, errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
class QSQLiteDriverPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline QSQLiteDriverPrivate() : access(0) {}
|
||||||
|
sqlite3 *access;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class QSQLiteResultPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QSQLiteResultPrivate(QSQLiteResult *res);
|
||||||
|
void cleanup();
|
||||||
|
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
|
||||||
|
// initializes the recordInfo and the cache
|
||||||
|
void initColumns(bool emptyResultset);
|
||||||
|
void finalize();
|
||||||
|
|
||||||
|
QSQLiteResult* q;
|
||||||
|
sqlite3 *access;
|
||||||
|
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
|
bool skippedStatus; // the status of the fetchNext() that's skipped
|
||||||
|
bool skipRow; // skip the next fetchNext()?
|
||||||
|
QSqlRecord rInf;
|
||||||
|
QVector<QVariant> firstRow;
|
||||||
|
};
|
||||||
|
|
||||||
|
QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult* res) : q(res), access(0),
|
||||||
|
stmt(0), skippedStatus(false), skipRow(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSQLiteResultPrivate::cleanup()
|
||||||
|
{
|
||||||
|
finalize();
|
||||||
|
rInf.clear();
|
||||||
|
skippedStatus = false;
|
||||||
|
skipRow = false;
|
||||||
|
q->setAt(QSql::BeforeFirstRow);
|
||||||
|
q->setActive(false);
|
||||||
|
q->cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSQLiteResultPrivate::finalize()
|
||||||
|
{
|
||||||
|
if (!stmt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
stmt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSQLiteResultPrivate::initColumns(bool emptyResultset)
|
||||||
|
{
|
||||||
|
int nCols = sqlite3_column_count(stmt);
|
||||||
|
if (nCols <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
q->init(nCols);
|
||||||
|
|
||||||
|
for (int i = 0; i < nCols; ++i) {
|
||||||
|
QString colName = QString::fromUtf16(
|
||||||
|
static_cast<const ushort *>(sqlite3_column_name16(stmt, i))
|
||||||
|
).remove(QLatin1Char('"'));
|
||||||
|
|
||||||
|
// must use typeName for resolving the type to match QSqliteDriver::record
|
||||||
|
QString typeName = QString::fromUtf16(
|
||||||
|
static_cast<const ushort *>(sqlite3_column_decltype16(stmt, i)));
|
||||||
|
|
||||||
|
int dotIdx = colName.lastIndexOf(QLatin1Char('.'));
|
||||||
|
QSqlField fld(colName.mid(dotIdx == -1 ? 0 : dotIdx + 1), qGetColumnType(typeName));
|
||||||
|
|
||||||
|
// sqlite3_column_type is documented to have undefined behavior if the result set is empty
|
||||||
|
int stp = emptyResultset ? -1 : sqlite3_column_type(stmt, i);
|
||||||
|
fld.setSqlType(stp);
|
||||||
|
rInf.append(fld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (skipRow) {
|
||||||
|
// already fetched
|
||||||
|
Q_ASSERT(!initialFetch);
|
||||||
|
skipRow = false;
|
||||||
|
for(int i=0;i<firstRow.count();i++)
|
||||||
|
values[i]=firstRow[i];
|
||||||
|
return skippedStatus;
|
||||||
|
}
|
||||||
|
skipRow = initialFetch;
|
||||||
|
|
||||||
|
if(initialFetch) {
|
||||||
|
firstRow.clear();
|
||||||
|
firstRow.resize(sqlite3_column_count(stmt));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stmt) {
|
||||||
|
q->setLastError(QSqlError(QCoreApplication::translate("QSQLiteResult", "Unable to fetch row"),
|
||||||
|
QCoreApplication::translate("QSQLiteResult", "No query"), QSqlError::ConnectionError));
|
||||||
|
q->setAt(QSql::AfterLastRow);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
res = sqlite3_blocking_step(stmt);
|
||||||
|
|
||||||
|
switch(res) {
|
||||||
|
case SQLITE_ROW:
|
||||||
|
// check to see if should fill out columns
|
||||||
|
if (rInf.isEmpty())
|
||||||
|
// must be first call.
|
||||||
|
initColumns(false);
|
||||||
|
if (idx < 0 && !initialFetch)
|
||||||
|
return true;
|
||||||
|
for (i = 0; i < rInf.count(); ++i) {
|
||||||
|
switch (sqlite3_column_type(stmt, i)) {
|
||||||
|
case SQLITE_BLOB:
|
||||||
|
values[i + idx] = QByteArray(static_cast<const char *>(
|
||||||
|
sqlite3_column_blob(stmt, i)),
|
||||||
|
sqlite3_column_bytes(stmt, i));
|
||||||
|
break;
|
||||||
|
case SQLITE_INTEGER:
|
||||||
|
values[i + idx] = sqlite3_column_int64(stmt, i);
|
||||||
|
break;
|
||||||
|
case SQLITE_FLOAT:
|
||||||
|
switch(q->numericalPrecisionPolicy()) {
|
||||||
|
case QSql::LowPrecisionInt32:
|
||||||
|
values[i + idx] = sqlite3_column_int(stmt, i);
|
||||||
|
break;
|
||||||
|
case QSql::LowPrecisionInt64:
|
||||||
|
values[i + idx] = sqlite3_column_int64(stmt, i);
|
||||||
|
break;
|
||||||
|
case QSql::LowPrecisionDouble:
|
||||||
|
case QSql::HighPrecision:
|
||||||
|
default:
|
||||||
|
values[i + idx] = sqlite3_column_double(stmt, i);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case SQLITE_NULL:
|
||||||
|
values[i + idx] = QVariant(QVariant::String);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
values[i + idx] = QString::fromUtf16(static_cast<const ushort *>(
|
||||||
|
sqlite3_column_text16(stmt, i)),
|
||||||
|
sqlite3_column_bytes16(stmt, i) / sizeof(ushort));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case SQLITE_DONE:
|
||||||
|
if (rInf.isEmpty())
|
||||||
|
// must be first call.
|
||||||
|
initColumns(true);
|
||||||
|
q->setAt(QSql::AfterLastRow);
|
||||||
|
sqlite3_reset(stmt);
|
||||||
|
return false;
|
||||||
|
case SQLITE_ERROR:
|
||||||
|
// SQLITE_ERROR is a generic error code and we must call sqlite3_reset()
|
||||||
|
// to get the specific error message.
|
||||||
|
res = sqlite3_reset(stmt);
|
||||||
|
q->setLastError(qMakeError(access, QCoreApplication::translate("QSQLiteResult",
|
||||||
|
"Unable to fetch row"), QSqlError::ConnectionError, res));
|
||||||
|
q->setAt(QSql::AfterLastRow);
|
||||||
|
return false;
|
||||||
|
case SQLITE_MISUSE:
|
||||||
|
case SQLITE_BUSY:
|
||||||
|
default:
|
||||||
|
// something wrong, don't get col info, but still return false
|
||||||
|
q->setLastError(qMakeError(access, QCoreApplication::translate("QSQLiteResult",
|
||||||
|
"Unable to fetch row"), QSqlError::ConnectionError, res));
|
||||||
|
sqlite3_reset(stmt);
|
||||||
|
q->setAt(QSql::AfterLastRow);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSQLiteResult::QSQLiteResult(const QSQLiteDriver* db)
|
||||||
|
: QSqlCachedResult(db)
|
||||||
|
{
|
||||||
|
d = new QSQLiteResultPrivate(this);
|
||||||
|
d->access = db->d->access;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSQLiteResult::~QSQLiteResult()
|
||||||
|
{
|
||||||
|
d->cleanup();
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSQLiteResult::virtual_hook(int id, void *data)
|
||||||
|
{
|
||||||
|
switch (id) {
|
||||||
|
case QSqlResult::DetachFromResultSet:
|
||||||
|
if (d->stmt)
|
||||||
|
sqlite3_reset(d->stmt);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
QSqlCachedResult::virtual_hook(id, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QSQLiteResult::reset(const QString &query)
|
||||||
|
{
|
||||||
|
if (!prepare(query))
|
||||||
|
return false;
|
||||||
|
return exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QSQLiteResult::prepare(const QString &query)
|
||||||
|
{
|
||||||
|
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d->cleanup();
|
||||||
|
|
||||||
|
setSelect(false);
|
||||||
|
|
||||||
|
#if (SQLITE_VERSION_NUMBER >= 3003011)
|
||||||
|
// int res = sqlite3_prepare16_v2(d->access, query.constData(), (query.size() + 1) * sizeof(QChar),
|
||||||
|
// &d->stmt, 0);
|
||||||
|
int res = sqlite3_blocking_prepare16_v2(d->access, query.constData(), (query.size() + 1) * sizeof(QChar),
|
||||||
|
&d->stmt, 0);
|
||||||
|
#else
|
||||||
|
int res = sqlite3_prepare16(d->access, query.constData(), (query.size() + 1) * sizeof(QChar),
|
||||||
|
&d->stmt, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (res != SQLITE_OK) {
|
||||||
|
setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
|
||||||
|
"Unable to execute statement"), QSqlError::StatementError, res));
|
||||||
|
d->finalize();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QSQLiteResult::exec()
|
||||||
|
{
|
||||||
|
const QVector<QVariant> values = boundValues();
|
||||||
|
|
||||||
|
d->skippedStatus = false;
|
||||||
|
d->skipRow = false;
|
||||||
|
d->rInf.clear();
|
||||||
|
clearValues();
|
||||||
|
setLastError(QSqlError());
|
||||||
|
|
||||||
|
int res = sqlite3_reset(d->stmt);
|
||||||
|
if (res != SQLITE_OK) {
|
||||||
|
setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
|
||||||
|
"Unable to reset statement"), QSqlError::StatementError, res));
|
||||||
|
d->finalize();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int paramCount = sqlite3_bind_parameter_count(d->stmt);
|
||||||
|
if (paramCount == values.count()) {
|
||||||
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
res = SQLITE_OK;
|
||||||
|
const QVariant value = values.at(i);
|
||||||
|
|
||||||
|
if (value.isNull()) {
|
||||||
|
res = sqlite3_bind_null(d->stmt, i + 1);
|
||||||
|
} else {
|
||||||
|
switch (value.type()) {
|
||||||
|
case QVariant::ByteArray: {
|
||||||
|
const QByteArray *ba = static_cast<const QByteArray*>(value.constData());
|
||||||
|
res = sqlite3_bind_blob(d->stmt, i + 1, ba->constData(),
|
||||||
|
ba->size(), SQLITE_STATIC);
|
||||||
|
break; }
|
||||||
|
case QVariant::Int:
|
||||||
|
res = sqlite3_bind_int(d->stmt, i + 1, value.toInt());
|
||||||
|
break;
|
||||||
|
case QVariant::Double:
|
||||||
|
res = sqlite3_bind_double(d->stmt, i + 1, value.toDouble());
|
||||||
|
break;
|
||||||
|
case QVariant::UInt:
|
||||||
|
case QVariant::LongLong:
|
||||||
|
res = sqlite3_bind_int64(d->stmt, i + 1, value.toLongLong());
|
||||||
|
break;
|
||||||
|
case QVariant::String: {
|
||||||
|
// lifetime of string == lifetime of its qvariant
|
||||||
|
const QString *str = static_cast<const QString*>(value.constData());
|
||||||
|
res = sqlite3_bind_text16(d->stmt, i + 1, str->utf16(),
|
||||||
|
(str->size()) * sizeof(QChar), SQLITE_STATIC);
|
||||||
|
break; }
|
||||||
|
default: {
|
||||||
|
QString str = value.toString();
|
||||||
|
// SQLITE_TRANSIENT makes sure that sqlite buffers the data
|
||||||
|
res = sqlite3_bind_text16(d->stmt, i + 1, str.utf16(),
|
||||||
|
(str.size()) * sizeof(QChar), SQLITE_TRANSIENT);
|
||||||
|
break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res != SQLITE_OK) {
|
||||||
|
setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
|
||||||
|
"Unable to bind parameters"), QSqlError::StatementError, res));
|
||||||
|
d->finalize();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setLastError(QSqlError(QCoreApplication::translate("QSQLiteResult",
|
||||||
|
"Parameter count mismatch"), QString(), QSqlError::StatementError));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
d->skippedStatus = d->fetchNext(d->firstRow, 0, true);
|
||||||
|
if (lastError().isValid()) {
|
||||||
|
setSelect(false);
|
||||||
|
setActive(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
setSelect(!d->rInf.isEmpty());
|
||||||
|
setActive(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QSQLiteResult::gotoNext(QSqlCachedResult::ValueCache& row, int idx)
|
||||||
|
{
|
||||||
|
return d->fetchNext(row, idx, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int QSQLiteResult::size()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QSQLiteResult::numRowsAffected()
|
||||||
|
{
|
||||||
|
return sqlite3_changes(d->access);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QSQLiteResult::lastInsertId() const
|
||||||
|
{
|
||||||
|
if (isActive()) {
|
||||||
|
qint64 id = sqlite3_last_insert_rowid(d->access);
|
||||||
|
if (id)
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlRecord QSQLiteResult::record() const
|
||||||
|
{
|
||||||
|
if (!isActive() || !isSelect())
|
||||||
|
return QSqlRecord();
|
||||||
|
return d->rInf;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QSQLiteResult::handle() const
|
||||||
|
{
|
||||||
|
return qVariantFromValue(d->stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
QSQLiteDriver::QSQLiteDriver(QObject * parent)
|
||||||
|
: QSqlDriver(parent)
|
||||||
|
{
|
||||||
|
d = new QSQLiteDriverPrivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSQLiteDriver::QSQLiteDriver(sqlite3 *connection, QObject *parent)
|
||||||
|
: QSqlDriver(parent)
|
||||||
|
{
|
||||||
|
d = new QSQLiteDriverPrivate();
|
||||||
|
d->access = connection;
|
||||||
|
setOpen(true);
|
||||||
|
setOpenError(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QSQLiteDriver::~QSQLiteDriver()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QSQLiteDriver::hasFeature(DriverFeature f) const
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case BLOB:
|
||||||
|
case Transactions:
|
||||||
|
case Unicode:
|
||||||
|
case LastInsertId:
|
||||||
|
case PreparedQueries:
|
||||||
|
case PositionalPlaceholders:
|
||||||
|
case SimpleLocking:
|
||||||
|
case FinishQuery:
|
||||||
|
case LowPrecisionNumbers:
|
||||||
|
return true;
|
||||||
|
case QuerySize:
|
||||||
|
case NamedPlaceholders:
|
||||||
|
case BatchOperations:
|
||||||
|
case EventNotifications:
|
||||||
|
case MultipleResultSets:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qGetSqliteTimeout(QString opts)
|
||||||
|
{
|
||||||
|
enum { DefaultTimeout = 5000 };
|
||||||
|
|
||||||
|
opts.remove(QLatin1Char(' '));
|
||||||
|
Q_FOREACH(const QString &option, opts.split(QLatin1Char(';'))) {
|
||||||
|
if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
|
||||||
|
bool ok;
|
||||||
|
int nt = option.mid(21).toInt(&ok);
|
||||||
|
if (ok)
|
||||||
|
return nt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DefaultTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qGetSqliteOpenMode(QString opts)
|
||||||
|
{
|
||||||
|
opts.remove(QLatin1Char(' '));
|
||||||
|
Q_FOREACH(const QString &option, opts.split(QLatin1Char(';'))) {
|
||||||
|
if (option == QLatin1String("QSQLITE_OPEN_READONLY"))
|
||||||
|
return SQLITE_OPEN_READONLY;
|
||||||
|
}
|
||||||
|
// The SQLITE_OPEN_NOMUTEX flag causes the database connection to be in the multi-thread mode
|
||||||
|
return SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SQLite dbs have no user name, passwords, hosts or ports.
|
||||||
|
just file names.
|
||||||
|
*/
|
||||||
|
bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &conOpts)
|
||||||
|
{
|
||||||
|
if (isOpen())
|
||||||
|
close();
|
||||||
|
|
||||||
|
if (db.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sqlite3_enable_shared_cache(1);
|
||||||
|
if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, qGetSqliteOpenMode(conOpts), NULL) == SQLITE_OK) {
|
||||||
|
sqlite3_busy_timeout(d->access, qGetSqliteTimeout(conOpts));
|
||||||
|
sqlite3_extended_result_codes(d->access, 1);
|
||||||
|
setOpen(true);
|
||||||
|
setOpenError(false);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
setLastError(qMakeError(d->access, tr("Error opening database"),
|
||||||
|
QSqlError::ConnectionError));
|
||||||
|
setOpenError(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSQLiteDriver::close()
|
||||||
|
{
|
||||||
|
if (isOpen()) {
|
||||||
|
if (sqlite3_close(d->access) != SQLITE_OK)
|
||||||
|
setLastError(qMakeError(d->access, tr("Error closing database"),
|
||||||
|
QSqlError::ConnectionError));
|
||||||
|
d->access = 0;
|
||||||
|
setOpen(false);
|
||||||
|
setOpenError(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlResult *QSQLiteDriver::createResult() const
|
||||||
|
{
|
||||||
|
return new QSQLiteResult(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QSQLiteDriver::beginTransaction()
|
||||||
|
{
|
||||||
|
if (!isOpen() || isOpenError())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QSqlQuery q(createResult());
|
||||||
|
if (!q.exec(QLatin1String("BEGIN"))) {
|
||||||
|
setLastError(QSqlError(tr("Unable to begin transaction"),
|
||||||
|
q.lastError().databaseText(), QSqlError::TransactionError));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QSQLiteDriver::commitTransaction()
|
||||||
|
{
|
||||||
|
if (!isOpen() || isOpenError())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QSqlQuery q(createResult());
|
||||||
|
if (!q.exec(QLatin1String("COMMIT"))) {
|
||||||
|
setLastError(QSqlError(tr("Unable to commit transaction"),
|
||||||
|
q.lastError().databaseText(), QSqlError::TransactionError));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QSQLiteDriver::rollbackTransaction()
|
||||||
|
{
|
||||||
|
if (!isOpen() || isOpenError())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QSqlQuery q(createResult());
|
||||||
|
if (!q.exec(QLatin1String("ROLLBACK"))) {
|
||||||
|
setLastError(QSqlError(tr("Unable to rollback transaction"),
|
||||||
|
q.lastError().databaseText(), QSqlError::TransactionError));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList QSQLiteDriver::tables(QSql::TableType type) const
|
||||||
|
{
|
||||||
|
QStringList res;
|
||||||
|
if (!isOpen())
|
||||||
|
return res;
|
||||||
|
|
||||||
|
QSqlQuery q(createResult());
|
||||||
|
q.setForwardOnly(true);
|
||||||
|
|
||||||
|
QString sql = QLatin1String("SELECT name FROM sqlite_master WHERE %1 "
|
||||||
|
"UNION ALL SELECT name FROM sqlite_temp_master WHERE %1");
|
||||||
|
if ((type & QSql::Tables) && (type & QSql::Views))
|
||||||
|
sql = sql.arg(QLatin1String("type='table' OR type='view'"));
|
||||||
|
else if (type & QSql::Tables)
|
||||||
|
sql = sql.arg(QLatin1String("type='table'"));
|
||||||
|
else if (type & QSql::Views)
|
||||||
|
sql = sql.arg(QLatin1String("type='view'"));
|
||||||
|
else
|
||||||
|
sql.clear();
|
||||||
|
|
||||||
|
if (!sql.isEmpty() && q.exec(sql)) {
|
||||||
|
while(q.next())
|
||||||
|
res.append(q.value(0).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & QSql::SystemTables) {
|
||||||
|
// there are no internal tables beside this one:
|
||||||
|
res.append(QLatin1String("sqlite_master"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QSqlIndex qGetTableInfo(QSqlQuery &q, const QString &tableName, bool onlyPIndex = false)
|
||||||
|
{
|
||||||
|
QString schema;
|
||||||
|
QString table(tableName);
|
||||||
|
int indexOfSeparator = tableName.indexOf(QLatin1Char('.'));
|
||||||
|
if (indexOfSeparator > -1) {
|
||||||
|
schema = tableName.left(indexOfSeparator).append(QLatin1Char('.'));
|
||||||
|
table = tableName.mid(indexOfSeparator + 1);
|
||||||
|
}
|
||||||
|
q.exec(QLatin1String("PRAGMA ") + schema + QLatin1String("table_info (") + _q_escapeIdentifier(table) + QLatin1String(")"));
|
||||||
|
|
||||||
|
QSqlIndex ind;
|
||||||
|
while (q.next()) {
|
||||||
|
bool isPk = q.value(5).toInt();
|
||||||
|
if (onlyPIndex && !isPk)
|
||||||
|
continue;
|
||||||
|
QString typeName = q.value(2).toString().toLower();
|
||||||
|
QSqlField fld(q.value(1).toString(), qGetColumnType(typeName));
|
||||||
|
if (isPk && (typeName == QLatin1String("integer")))
|
||||||
|
// INTEGER PRIMARY KEY fields are auto-generated in sqlite
|
||||||
|
// INT PRIMARY KEY is not the same as INTEGER PRIMARY KEY!
|
||||||
|
fld.setAutoValue(true);
|
||||||
|
fld.setRequired(q.value(3).toInt() != 0);
|
||||||
|
fld.setDefaultValue(q.value(4));
|
||||||
|
ind.append(fld);
|
||||||
|
}
|
||||||
|
return ind;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlIndex QSQLiteDriver::primaryIndex(const QString &tblname) const
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
return QSqlIndex();
|
||||||
|
|
||||||
|
QString table = tblname;
|
||||||
|
if (isIdentifierEscaped(table, QSqlDriver::TableName))
|
||||||
|
table = stripDelimiters(table, QSqlDriver::TableName);
|
||||||
|
|
||||||
|
QSqlQuery q(createResult());
|
||||||
|
q.setForwardOnly(true);
|
||||||
|
return qGetTableInfo(q, table, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlRecord QSQLiteDriver::record(const QString &tbl) const
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
return QSqlRecord();
|
||||||
|
|
||||||
|
QString table = tbl;
|
||||||
|
if (isIdentifierEscaped(table, QSqlDriver::TableName))
|
||||||
|
table = stripDelimiters(table, QSqlDriver::TableName);
|
||||||
|
|
||||||
|
QSqlQuery q(createResult());
|
||||||
|
q.setForwardOnly(true);
|
||||||
|
return qGetTableInfo(q, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QSQLiteDriver::handle() const
|
||||||
|
{
|
||||||
|
return qVariantFromValue(d->access);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(type);
|
||||||
|
return _q_escapeIdentifier(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
123
akonadi/qsqlite/src/qsql_sqlite.h
Normal file
123
akonadi/qsqlite/src/qsql_sqlite.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the QtSql module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial Usage
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain
|
||||||
|
** additional rights. These rights are described in the Nokia Qt LGPL
|
||||||
|
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
||||||
|
** package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://www.qtsoftware.com/contact.
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSQL_SQLITE_H
|
||||||
|
#define QSQL_SQLITE_H
|
||||||
|
|
||||||
|
#include <QtSql/qsqldriver.h>
|
||||||
|
#include <QtSql/qsqlresult.h>
|
||||||
|
#include <QtSql/private/qsqlcachedresult_p.h>
|
||||||
|
|
||||||
|
struct sqlite3;
|
||||||
|
|
||||||
|
#ifdef QT_PLUGIN
|
||||||
|
#define Q_EXPORT_SQLDRIVER_SQLITE
|
||||||
|
#else
|
||||||
|
#define Q_EXPORT_SQLDRIVER_SQLITE Q_SQL_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QT_BEGIN_HEADER
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QSQLiteDriverPrivate;
|
||||||
|
class QSQLiteResultPrivate;
|
||||||
|
class QSQLiteDriver;
|
||||||
|
|
||||||
|
class QSQLiteResult : public QSqlCachedResult
|
||||||
|
{
|
||||||
|
friend class QSQLiteDriver;
|
||||||
|
friend class QSQLiteResultPrivate;
|
||||||
|
public:
|
||||||
|
explicit QSQLiteResult(const QSQLiteDriver* db);
|
||||||
|
~QSQLiteResult();
|
||||||
|
QVariant handle() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool gotoNext(QSqlCachedResult::ValueCache& row, int idx);
|
||||||
|
bool reset(const QString &query);
|
||||||
|
bool prepare(const QString &query);
|
||||||
|
bool exec();
|
||||||
|
int size();
|
||||||
|
int numRowsAffected();
|
||||||
|
QVariant lastInsertId() const;
|
||||||
|
QSqlRecord record() const;
|
||||||
|
void virtual_hook(int id, void *data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSQLiteResultPrivate* d;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Q_EXPORT_SQLDRIVER_SQLITE QSQLiteDriver : public QSqlDriver
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
friend class QSQLiteResult;
|
||||||
|
public:
|
||||||
|
explicit QSQLiteDriver(QObject *parent = 0);
|
||||||
|
explicit QSQLiteDriver(sqlite3 *connection, QObject *parent = 0);
|
||||||
|
~QSQLiteDriver();
|
||||||
|
bool hasFeature(DriverFeature f) const;
|
||||||
|
bool open(const QString & db,
|
||||||
|
const QString & user,
|
||||||
|
const QString & password,
|
||||||
|
const QString & host,
|
||||||
|
int port,
|
||||||
|
const QString & connOpts);
|
||||||
|
void close();
|
||||||
|
QSqlResult *createResult() const;
|
||||||
|
bool beginTransaction();
|
||||||
|
bool commitTransaction();
|
||||||
|
bool rollbackTransaction();
|
||||||
|
QStringList tables(QSql::TableType) const;
|
||||||
|
|
||||||
|
QSqlRecord record(const QString& tablename) const;
|
||||||
|
QSqlIndex primaryIndex(const QString &table) const;
|
||||||
|
QVariant handle() const;
|
||||||
|
QString escapeIdentifier(const QString &identifier, IdentifierType) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSQLiteDriverPrivate* d;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_HEADER
|
||||||
|
|
||||||
|
#endif // QSQL_SQLITE_H
|
82
akonadi/qsqlite/src/smain.cpp
Normal file
82
akonadi/qsqlite/src/smain.cpp
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial Usage
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain
|
||||||
|
** additional rights. These rights are described in the Nokia Qt LGPL
|
||||||
|
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
||||||
|
** package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://www.qtsoftware.com/contact.
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtSql/QSqlDriverPlugin>
|
||||||
|
|
||||||
|
#include "qsql_sqlite.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QSQLiteDriverPlugin : public QSqlDriverPlugin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QSQLiteDriverPlugin();
|
||||||
|
|
||||||
|
QSqlDriver* create(const QString &);
|
||||||
|
QStringList keys() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
QSQLiteDriverPlugin::QSQLiteDriverPlugin()
|
||||||
|
: QSqlDriverPlugin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlDriver* QSQLiteDriverPlugin::create(const QString &name)
|
||||||
|
{
|
||||||
|
if (name == QLatin1String("QSQLITE3")) {
|
||||||
|
QSQLiteDriver* driver = new QSQLiteDriver();
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList QSQLiteDriverPlugin::keys() const
|
||||||
|
{
|
||||||
|
QStringList l;
|
||||||
|
l << QLatin1String("QSQLITE3");
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EXPORT_STATIC_PLUGIN(QSQLiteDriverPlugin)
|
||||||
|
Q_EXPORT_PLUGIN2(qsqlite3, QSQLiteDriverPlugin)
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue